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

Side by Side Diff: chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm

Issue 12255023: [Media Galleries] Switch Mac MTP delegate to async interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Support overlapped dir reads Created 7 years, 8 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
OLDNEW
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 #import <Foundation/Foundation.h> 5 #import <Foundation/Foundation.h>
6 #import <ImageCaptureCore/ImageCaptureCore.h> 6 #import <ImageCaptureCore/ImageCaptureCore.h>
7 7
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
9 #include "base/mac/cocoa_protocols.h" 10 #include "base/mac/cocoa_protocols.h"
10 #include "base/mac/foundation_util.h" 11 #include "base/mac/foundation_util.h"
11 #include "base/memory/scoped_nsobject.h" 12 #include "base/memory/scoped_nsobject.h"
12 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/run_loop.h"
13 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
14 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
15 #include "base/test/sequenced_worker_pool_owner.h" 17 #include "base/test/sequenced_worker_pool_owner.h"
16 #include "base/threading/sequenced_worker_pool.h" 18 #include "base/threading/sequenced_worker_pool.h"
17 #include "chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h" 19 #include "chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h"
18 #include "chrome/browser/storage_monitor/image_capture_device_manager.h" 20 #include "chrome/browser/storage_monitor/image_capture_device_manager.h"
19 #include "chrome/browser/storage_monitor/test_storage_monitor.h" 21 #include "chrome/browser/storage_monitor/test_storage_monitor.h"
20 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
21 #include "content/public/test/test_browser_thread.h" 23 #include "content/public/test/test_browser_thread.h"
22 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 event->Signal(); 170 event->Signal();
169 } 171 }
170 172
171 class MTPDeviceDelegateImplMacTest : public testing::Test { 173 class MTPDeviceDelegateImplMacTest : public testing::Test {
172 public: 174 public:
173 MTPDeviceDelegateImplMacTest() : camera_(NULL), delegate_(NULL) {} 175 MTPDeviceDelegateImplMacTest() : camera_(NULL), delegate_(NULL) {}
174 176
175 virtual void SetUp() OVERRIDE { 177 virtual void SetUp() OVERRIDE {
176 ui_thread_.reset(new content::TestBrowserThread( 178 ui_thread_.reset(new content::TestBrowserThread(
177 content::BrowserThread::UI, &message_loop_)); 179 content::BrowserThread::UI, &message_loop_));
180 file_thread_.reset(new content::TestBrowserThread(
181 content::BrowserThread::FILE, &message_loop_));
182 io_thread_.reset(new content::TestBrowserThread(
183 content::BrowserThread::IO));
184 ASSERT_TRUE(io_thread_->Start());
185 // Need a waitable event on io thread startup?
178 186
179 manager_.SetNotifications(monitor_.receiver()); 187 manager_.SetNotifications(monitor_.receiver());
180 188
181 camera_ = [MockMTPICCameraDevice alloc]; 189 camera_ = [MockMTPICCameraDevice alloc];
182 id<ICDeviceBrowserDelegate> delegate = manager_.device_browser(); 190 id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
183 [delegate deviceBrowser:nil didAddDevice:camera_ moreComing:NO]; 191 [delegate deviceBrowser:nil didAddDevice:camera_ moreComing:NO];
184 192
185 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 193 delegate_ = new chrome::MTPDeviceDelegateImplMac("id", "/ic:id");
186 task_runner_ = pool->GetSequencedTaskRunner( 194 }
187 pool->GetNamedSequenceToken("token-name")); 195
188 delegate_ = new chrome::MTPDeviceDelegateImplMac( 196 void OnError(base::WaitableEvent* event, base::PlatformFileError error) {
189 "id", "/ic:id", task_runner_.get()); 197 error_ = error;
198 event->Signal();
199 }
200
201 void OnFileInfo(base::WaitableEvent* event,
202 const base::PlatformFileInfo& info) {
203 error_ = base::PLATFORM_FILE_OK;
204 info_ = info;
205 event->Signal();
206 }
207
208 void OnReadDir(base::WaitableEvent* event,
209 const fileapi::AsyncFileUtil::EntryList& files,
210 bool has_more) {
211 error_ = base::PLATFORM_FILE_OK;
212 ASSERT_FALSE(has_more);
213 file_list_ = files;
214 event->Signal();
215 }
216
217 void OnDownload(base::WaitableEvent* event,
218 const base::PlatformFileInfo& file_info,
219 const base::FilePath& local_path) {
220 error_ = base::PLATFORM_FILE_OK;
221 event->Signal();
222 }
223
224 base::PlatformFileError GetFileInfo(const base::FilePath& path,
225 base::PlatformFileInfo* info) {
226 base::WaitableEvent wait(true, false);
227 delegate_->GetFileInfo(
228 path,
229 base::Bind(&MTPDeviceDelegateImplMacTest::OnFileInfo,
230 base::Unretained(this),
231 &wait),
232 base::Bind(&MTPDeviceDelegateImplMacTest::OnError,
233 base::Unretained(this),
234 &wait));
235 base::RunLoop loop;
236 loop.RunUntilIdle();
237 wait.Wait();
238 *info = info_;
239 return error_;
240 }
241
242 base::PlatformFileError ReadDir(const base::FilePath& path) {
243 base::WaitableEvent wait(true, false);
244 delegate_->ReadDirectory(
245 path,
246 base::Bind(&MTPDeviceDelegateImplMacTest::OnReadDir,
247 base::Unretained(this),
248 &wait),
249 base::Bind(&MTPDeviceDelegateImplMacTest::OnError,
250 base::Unretained(this),
251 &wait));
252 base::RunLoop loop;
253 loop.RunUntilIdle();
254 wait.Wait();
255 return error_;
256 }
257
258 base::PlatformFileError DownloadFile(
259 const base::FilePath& path,
260 const base::FilePath& local_path) {
261 base::WaitableEvent wait(true, false);
262 delegate_->CreateSnapshotFile(
263 path, local_path,
264 base::Bind(&MTPDeviceDelegateImplMacTest::OnDownload,
265 base::Unretained(this),
266 &wait),
267 base::Bind(&MTPDeviceDelegateImplMacTest::OnError,
268 base::Unretained(this),
269 &wait));
270 base::RunLoop loop;
271 loop.RunUntilIdle();
272 wait.Wait();
273 return error_;
190 } 274 }
191 275
192 virtual void TearDown() OVERRIDE { 276 virtual void TearDown() OVERRIDE {
193 id<ICDeviceBrowserDelegate> delegate = manager_.device_browser(); 277 id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
194 [delegate deviceBrowser:nil didRemoveDevice:camera_ moreGoing:NO]; 278 [delegate deviceBrowser:nil didRemoveDevice:camera_ moreGoing:NO];
195 279
196 task_runner_->PostTask(FROM_HERE, 280 delegate_->CancelPendingTasksAndDeleteDelegate();
197 base::Bind(&chrome::MTPDeviceDelegateImplMac:: 281
198 CancelPendingTasksAndDeleteDelegate, 282 io_thread_->Stop();
199 base::Unretained(delegate_)));
200 } 283 }
201 284
202 protected: 285 protected:
203 MessageLoopForUI message_loop_; 286 MessageLoopForUI message_loop_;
287 // Note: threads must be made in this order: UI > FILE > IO
204 scoped_ptr<content::TestBrowserThread> ui_thread_; 288 scoped_ptr<content::TestBrowserThread> ui_thread_;
289 scoped_ptr<content::TestBrowserThread> file_thread_;
290 scoped_ptr<content::TestBrowserThread> io_thread_;
291 base::ScopedTempDir temp_dir_;
205 chrome::test::TestStorageMonitor monitor_; 292 chrome::test::TestStorageMonitor monitor_;
206 chrome::ImageCaptureDeviceManager manager_; 293 chrome::ImageCaptureDeviceManager manager_;
207 ICCameraDevice* camera_; 294 MockMTPICCameraDevice* camera_;
208 scoped_refptr<base::SequencedTaskRunner> task_runner_;
209 295
210 // This object needs special deletion inside the above |task_runner_|. 296 // This object needs special deletion inside the above |task_runner_|.
211 chrome::MTPDeviceDelegateImplMac* delegate_; 297 chrome::MTPDeviceDelegateImplMac* delegate_;
212 298
299 base::PlatformFileError error_;
300 base::PlatformFileInfo info_;
301 fileapi::AsyncFileUtil::EntryList file_list_;
302
213 private: 303 private:
214 DISALLOW_COPY_AND_ASSIGN(MTPDeviceDelegateImplMacTest); 304 DISALLOW_COPY_AND_ASSIGN(MTPDeviceDelegateImplMacTest);
215 }; 305 };
216 306
217 TEST_F(MTPDeviceDelegateImplMacTest, TestGetRootFileInfo) { 307 TEST_F(MTPDeviceDelegateImplMacTest, TestGetRootFileInfo) {
218 base::PlatformFileInfo info; 308 base::PlatformFileInfo info;
219 // Making a fresh delegate should have a single file entry for the synthetic 309 // Making a fresh delegate should have a single file entry for the synthetic
220 // root directory, with the name equal to the device id string. 310 // root directory, with the name equal to the device id string.
221 EXPECT_EQ(base::PLATFORM_FILE_OK, 311 EXPECT_EQ(base::PLATFORM_FILE_OK,
222 delegate_->GetFileInfo(base::FilePath("/ic:id"), &info)); 312 GetFileInfo(base::FilePath("/ic:id"), &info));
223 EXPECT_TRUE(info.is_directory); 313 EXPECT_TRUE(info.is_directory);
224 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 314 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
225 delegate_->GetFileInfo(base::FilePath("/nonexistent"), &info)); 315 GetFileInfo(base::FilePath("/nonexistent"), &info));
226 316
227 // Signal the delegate that no files are coming. 317 // Signal the delegate that no files are coming.
228 delegate_->NoMoreItems(); 318 delegate_->NoMoreItems();
229 319
230 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator = 320 EXPECT_EQ(base::PLATFORM_FILE_OK, ReadDir(base::FilePath("/ic:id")));
231 delegate_->CreateFileEnumerator(base::FilePath("/ic:id"), true); 321 EXPECT_EQ(0U, file_list_.size());
232 EXPECT_TRUE(enumerator->Next().empty());
233 } 322 }
234 323
235 TEST_F(MTPDeviceDelegateImplMacTest, TestGetFileInfo) { 324 TEST_F(MTPDeviceDelegateImplMacTest, TestGetFileInfo) {
236 base::Time time1 = base::Time::Now(); 325 base::Time time1 = base::Time::Now();
237 base::PlatformFileInfo info1; 326 base::PlatformFileInfo info1;
238 info1.size = 1; 327 info1.size = 1;
239 info1.is_directory = false; 328 info1.is_directory = false;
240 info1.is_symbolic_link = false; 329 info1.is_symbolic_link = false;
241 info1.last_modified = time1; 330 info1.last_modified = time1;
242 info1.last_accessed = time1; 331 info1.last_accessed = time1;
243 info1.creation_time = time1; 332 info1.creation_time = time1;
244 delegate_->ItemAdded("name1", info1); 333 delegate_->ItemAdded("name1", info1);
245 334
246 base::PlatformFileInfo info; 335 base::PlatformFileInfo info;
247 EXPECT_EQ(base::PLATFORM_FILE_OK, 336 EXPECT_EQ(base::PLATFORM_FILE_OK,
248 delegate_->GetFileInfo(base::FilePath("/ic:id/name1"), &info)); 337 GetFileInfo(base::FilePath("/ic:id/name1"), &info));
249 EXPECT_EQ(info1.size, info.size); 338 EXPECT_EQ(info1.size, info.size);
250 EXPECT_EQ(info1.is_directory, info.is_directory); 339 EXPECT_EQ(info1.is_directory, info.is_directory);
251 EXPECT_EQ(info1.last_modified, info.last_modified); 340 EXPECT_EQ(info1.last_modified, info.last_modified);
252 EXPECT_EQ(info1.last_accessed, info.last_accessed); 341 EXPECT_EQ(info1.last_accessed, info.last_accessed);
253 EXPECT_EQ(info1.creation_time, info.creation_time); 342 EXPECT_EQ(info1.creation_time, info.creation_time);
254 343
255 info1.size = 2; 344 info1.size = 2;
256 delegate_->ItemAdded("name2", info1); 345 delegate_->ItemAdded("name2", info1);
257 delegate_->NoMoreItems(); 346 delegate_->NoMoreItems();
258 347
259 EXPECT_EQ(base::PLATFORM_FILE_OK, 348 EXPECT_EQ(base::PLATFORM_FILE_OK,
260 delegate_->GetFileInfo(base::FilePath("/ic:id/name2"), &info)); 349 GetFileInfo(base::FilePath("/ic:id/name2"), &info));
261 EXPECT_EQ(info1.size, info.size); 350 EXPECT_EQ(info1.size, info.size);
262 351
263 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator = 352 EXPECT_EQ(base::PLATFORM_FILE_OK, ReadDir(base::FilePath("/ic:id")));
264 delegate_->CreateFileEnumerator(base::FilePath("/ic:id"), true);
265 base::FilePath next = enumerator->Next();
266 ASSERT_FALSE(next.empty());
267 EXPECT_EQ(1, enumerator->Size());
268 EXPECT_EQ(time1, enumerator->LastModifiedTime());
269 EXPECT_FALSE(enumerator->IsDirectory());
270 EXPECT_EQ("/ic:id/name1", next.value());
271 353
272 next = enumerator->Next(); 354 ASSERT_EQ(2U, file_list_.size());
273 ASSERT_FALSE(next.empty()); 355 EXPECT_EQ(time1, file_list_[0].last_modified_time);
274 EXPECT_EQ(2, enumerator->Size()); 356 EXPECT_FALSE(file_list_[0].is_directory);
275 EXPECT_EQ(time1, enumerator->LastModifiedTime()); 357 EXPECT_EQ("/ic:id/name1", file_list_[0].name);
276 EXPECT_FALSE(enumerator->IsDirectory());
277 EXPECT_EQ("/ic:id/name2", next.value());
278 358
279 next = enumerator->Next(); 359 EXPECT_EQ(time1, file_list_[1].last_modified_time);
280 EXPECT_TRUE(next.empty()); 360 EXPECT_FALSE(file_list_[1].is_directory);
361 EXPECT_EQ("/ic:id/name2", file_list_[1].name);
281 } 362 }
282 363
283 TEST_F(MTPDeviceDelegateImplMacTest, TestIgnoreDirectories) { 364 TEST_F(MTPDeviceDelegateImplMacTest, TestIgnoreDirectories) {
284 base::Time time1 = base::Time::Now(); 365 base::Time time1 = base::Time::Now();
285 base::PlatformFileInfo info1; 366 base::PlatformFileInfo info1;
286 info1.size = 1; 367 info1.size = 1;
287 info1.is_directory = false; 368 info1.is_directory = false;
288 info1.is_symbolic_link = false; 369 info1.is_symbolic_link = false;
289 info1.last_modified = time1; 370 info1.last_modified = time1;
290 info1.last_accessed = time1; 371 info1.last_accessed = time1;
291 info1.creation_time = time1; 372 info1.creation_time = time1;
292 delegate_->ItemAdded("name1", info1); 373 delegate_->ItemAdded("name1", info1);
293 374
294 info1.is_directory = true; 375 info1.is_directory = true;
295 delegate_->ItemAdded("dir1", info1); 376 delegate_->ItemAdded("dir1", info1);
296 delegate_->ItemAdded("dir2", info1); 377 delegate_->ItemAdded("dir2", info1);
297 378
298 info1.is_directory = false; 379 info1.is_directory = false;
299 delegate_->ItemAdded("name2", info1); 380 delegate_->ItemAdded("name2", info1);
300 delegate_->NoMoreItems(); 381 delegate_->NoMoreItems();
301 382
302 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator = 383 EXPECT_EQ(base::PLATFORM_FILE_OK, ReadDir(base::FilePath("/ic:id")));
303 delegate_->CreateFileEnumerator(base::FilePath("/ic:id"), true);
304 base::FilePath next = enumerator->Next();
305 ASSERT_FALSE(next.empty());
306 EXPECT_EQ("/ic:id/name1", next.value());
307 384
308 next = enumerator->Next(); 385 ASSERT_EQ(2U, file_list_.size());
309 ASSERT_FALSE(next.empty()); 386 EXPECT_EQ(time1, file_list_[0].last_modified_time);
310 EXPECT_EQ("/ic:id/name2", next.value()); 387 EXPECT_FALSE(file_list_[0].is_directory);
388 EXPECT_EQ("/ic:id/name1", file_list_[0].name);
311 389
312 next = enumerator->Next(); 390 EXPECT_EQ(time1, file_list_[1].last_modified_time);
313 EXPECT_TRUE(next.empty()); 391 EXPECT_FALSE(file_list_[1].is_directory);
392 EXPECT_EQ("/ic:id/name2", file_list_[1].name);
314 } 393 }
315 394
316 TEST_F(MTPDeviceDelegateImplMacTest, EnumeratorWaitsForEntries) { 395 TEST_F(MTPDeviceDelegateImplMacTest, TestDownload) {
317 base::Time time1 = base::Time::Now(); 396 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
318 base::PlatformFileInfo info1; 397 base::Time t1 = base::Time::Now();
319 info1.size = 1; 398 base::PlatformFileInfo info;
320 info1.is_directory = false; 399 info.size = 4;
321 info1.is_symbolic_link = false; 400 info.is_directory = false;
322 info1.last_modified = time1; 401 info.is_symbolic_link = false;
323 info1.last_accessed = time1; 402 info.last_modified = t1;
324 info1.creation_time = time1; 403 info.last_accessed = t1;
325 delegate_->ItemAdded("name1", info1); 404 info.creation_time = t1;
405 std::string kTestFileName("filename");
406 scoped_nsobject<MockMTPICCameraFile> picture1(
407 [[MockMTPICCameraFile alloc]
408 init:base::SysUTF8ToNSString(kTestFileName)]);
409 [camera_ addMediaFile:picture1];
410 delegate_->ItemAdded(kTestFileName, info);
411 delegate_->NoMoreItems();
326 412
327 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator = 413 EXPECT_EQ(base::PLATFORM_FILE_OK, ReadDir(base::FilePath("/ic:id")));
328 delegate_->CreateFileEnumerator(base::FilePath("/ic:id"), true); 414 ASSERT_EQ(1U, file_list_.size());
329 // Event is manually reset, initially unsignaled 415 ASSERT_EQ("/ic:id/filename", file_list_[0].name);
330 base::WaitableEvent event(true, false);
331 base::FilePath next;
332 task_runner_->PostTask(FROM_HERE,
333 base::Bind(&EnumerateAndSignal,
334 enumerator.get(), &event, &next));
335 message_loop_.RunUntilIdle();
336 ASSERT_TRUE(event.IsSignaled());
337 EXPECT_EQ("/ic:id/name1", next.value());
338 416
339 event.Reset(); 417 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
418 DownloadFile(base::FilePath("/ic:id/nonexist"),
419 temp_dir_.path().Append("target")));
340 420
341 // This method will block until it is sure there are no more items. 421 EXPECT_EQ(base::PLATFORM_FILE_OK,
342 task_runner_->PostTask(FROM_HERE, 422 DownloadFile(base::FilePath("/ic:id/filename"),
343 base::Bind(&EnumerateAndSignal, 423 temp_dir_.path().Append("target")));
344 enumerator.get(), &event, &next)); 424 std::string contents;
345 message_loop_.RunUntilIdle(); 425 EXPECT_TRUE(file_util::ReadFileToString(temp_dir_.path().Append("target"),
346 ASSERT_FALSE(event.IsSignaled()); 426 &contents));
347 delegate_->NoMoreItems(); 427 EXPECT_EQ(kTestFileContents, contents);
348 event.Wait();
349 ASSERT_TRUE(event.IsSignaled());
350 EXPECT_TRUE(next.empty());
351 message_loop_.RunUntilIdle();
352 } 428 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698