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

Side by Side Diff: chrome/browser/media_gallery/removable_device_notifications_linux_unittest.cc

Issue 10919051: Move device notification impl out of chrome/browser/media_gallery (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: modify for chromeos and win Created 8 years, 3 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // RemovableDeviceNotificationsLinux unit tests.
6
7 #include "chrome/browser/media_gallery/removable_device_notifications_linux.h"
8
9 #include <mntent.h>
10 #include <stdio.h>
11
12 #include <string>
13
14 #include "base/file_util.h"
15 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/message_loop.h"
18 #include "base/scoped_temp_dir.h"
19 #include "base/system_monitor/system_monitor.h"
20 #include "base/test/mock_devices_changed_observer.h"
21 #include "base/utf_string_conversions.h"
22 #include "chrome/browser/media_gallery/media_storage_util.h"
23 #include "content/public/test/test_browser_thread.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace chrome {
27
28 namespace {
29
30 using testing::_;
31
32 const char kValidFS[] = "vfat";
33 const char kInvalidFS[] = "invalidfs";
34
35 const char kInvalidPath[] = "invalid path does not exist";
36
37 const char kDeviceDCIM1[] = "d1";
38 const char kDeviceDCIM2[] = "d2";
39 const char kDeviceDCIM3[] = "d3";
40 const char kDeviceNoDCIM[] = "d4";
41 const char kDeviceFixed[] = "d5";
42
43 const char kInvalidDevice[] = "invalid_device";
44
45 const char kMountPointA[] = "mnt_a";
46 const char kMountPointB[] = "mnt_b";
47 const char kMountPointC[] = "mnt_c";
48
49 const char kDCIM[] = "DCIM";
50
51 struct TestDeviceData {
52 const char* device_path;
53 const char* unique_id;
54 const char* device_name;
55 MediaStorageUtil::Type type;
56 };
57
58 const TestDeviceData kTestDeviceData[] = {
59 {kDeviceDCIM1, "UUID:FFF0-000F", "TEST_USB_MODEL_1",
60 MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM},
61 {kDeviceDCIM2, "VendorModelSerial:ComName:Model2010:8989", "TEST_USB_MODEL_2",
62 MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM},
63 {kDeviceDCIM3, "VendorModelSerial:::WEM319X792", "TEST_USB_MODEL_3",
64 MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM},
65 {kDeviceNoDCIM, "UUID:ABCD-1234", "TEST_USB_MODEL_4",
66 MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM},
67 {kDeviceFixed, "UUID:743A91FD2349", "TEST_USB_MODEL_5",
68 MediaStorageUtil::FIXED_MASS_STORAGE},
69 };
70
71 bool GetDeviceInfo(const FilePath& device_path, std::string* id,
72 string16* name, bool* removable) {
73 for (size_t i = 0; i < arraysize(kTestDeviceData); i++) {
74 if (device_path.value() == kTestDeviceData[i].device_path) {
75 if (id)
76 *id = kTestDeviceData[i].unique_id;
77 if (name)
78 *name = ASCIIToUTF16(kTestDeviceData[i].device_name);
79 if (removable) {
80 MediaStorageUtil::Type type = kTestDeviceData[i].type;
81 *removable =
82 (type == MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM) ||
83 (type == MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM);
84 }
85 return true;
86 }
87 }
88 return false;
89 }
90
91 std::string GetDeviceId(const std::string& device) {
92 for (size_t i = 0; i < arraysize(kTestDeviceData); i++) {
93 if (device == kTestDeviceData[i].device_path) {
94 return MediaStorageUtil::MakeDeviceId(kTestDeviceData[i].type,
95 kTestDeviceData[i].unique_id);
96 }
97 }
98 if (device == kInvalidDevice) {
99 return MediaStorageUtil::MakeDeviceId(MediaStorageUtil::FIXED_MASS_STORAGE,
100 kInvalidDevice);
101 }
102 return std::string();
103 }
104 string16 GetDeviceName(const std::string& device) {
105 for (size_t i = 0; i < arraysize(kTestDeviceData); i++) {
106 if (device == kTestDeviceData[i].device_path)
107 return ASCIIToUTF16(kTestDeviceData[i].device_name);
108 }
109 return string16();
110 }
111
112 class RemovableDeviceNotificationsLinuxTestWrapper
113 : public RemovableDeviceNotificationsLinux {
114 public:
115 RemovableDeviceNotificationsLinuxTestWrapper(const FilePath& path,
116 MessageLoop* message_loop)
117 : RemovableDeviceNotificationsLinux(path, &GetDeviceInfo),
118 message_loop_(message_loop) {
119 }
120
121 private:
122 // Avoids code deleting the object while there are references to it.
123 // Aside from the base::RefCountedThreadSafe friend class, any attempts to
124 // call this dtor will result in a compile-time error.
125 ~RemovableDeviceNotificationsLinuxTestWrapper() {}
126
127 virtual void OnFilePathChanged(const FilePath& path, bool error) OVERRIDE {
128 RemovableDeviceNotificationsLinux::OnFilePathChanged(path, error);
129 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
130 }
131
132 MessageLoop* message_loop_;
133
134 DISALLOW_COPY_AND_ASSIGN(RemovableDeviceNotificationsLinuxTestWrapper);
135 };
136
137 class RemovableDeviceNotificationLinuxTest : public testing::Test {
138 public:
139 struct MtabTestData {
140 MtabTestData(const std::string& mount_device,
141 const std::string& mount_point,
142 const std::string& mount_type)
143 : mount_device(mount_device),
144 mount_point(mount_point),
145 mount_type(mount_type) {
146 }
147
148 const std::string mount_device;
149 const std::string mount_point;
150 const std::string mount_type;
151 };
152
153 RemovableDeviceNotificationLinuxTest()
154 : message_loop_(MessageLoop::TYPE_IO),
155 file_thread_(content::BrowserThread::FILE, &message_loop_) {
156 }
157 virtual ~RemovableDeviceNotificationLinuxTest() {}
158
159 protected:
160 virtual void SetUp() OVERRIDE {
161 mock_devices_changed_observer_.reset(new base::MockDevicesChangedObserver);
162 system_monitor_.AddDevicesChangedObserver(
163 mock_devices_changed_observer_.get());
164
165 // Create and set up a temp dir with files for the test.
166 ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
167 FilePath test_dir = scoped_temp_dir_.path().AppendASCII("test_etc");
168 ASSERT_TRUE(file_util::CreateDirectory(test_dir));
169 mtab_file_ = test_dir.AppendASCII("test_mtab");
170 MtabTestData initial_test_data[] = {
171 MtabTestData("dummydevice", "dummydir", kInvalidFS),
172 };
173 WriteToMtab(initial_test_data,
174 arraysize(initial_test_data),
175 true /* overwrite */);
176
177 // Initialize the test subject.
178 notifications_ = new RemovableDeviceNotificationsLinuxTestWrapper(
179 mtab_file_, &message_loop_);
180 notifications_->Init();
181 message_loop_.RunAllPending();
182 }
183
184 virtual void TearDown() OVERRIDE {
185 message_loop_.RunAllPending();
186 notifications_ = NULL;
187 system_monitor_.RemoveDevicesChangedObserver(
188 mock_devices_changed_observer_.get());
189 }
190
191 // Append mtab entries from the |data| array of size |data_size| to the mtab
192 // file, and run the message loop.
193 void AppendToMtabAndRunLoop(const MtabTestData* data, size_t data_size) {
194 WriteToMtab(data, data_size, false /* do not overwrite */);
195 message_loop_.Run();
196 }
197
198 // Overwrite the mtab file with mtab entries from the |data| array of size
199 // |data_size|, and run the message loop.
200 void OverwriteMtabAndRunLoop(const MtabTestData* data, size_t data_size) {
201 WriteToMtab(data, data_size, true /* overwrite */);
202 message_loop_.Run();
203 }
204
205 // Simplied version of OverwriteMtabAndRunLoop() that just deletes all the
206 // entries in the mtab file.
207 void WriteEmptyMtabAndRunLoop() {
208 OverwriteMtabAndRunLoop(NULL, // No data.
209 0); // No data length.
210 }
211
212 // Create a directory named |dir| relative to the test directory.
213 // It has a DCIM directory, so RemovableDeviceNotificationsLinux recognizes it
214 // as a media directory.
215 FilePath CreateMountPointWithDCIMDir(const std::string& dir) {
216 return CreateMountPoint(dir, true /* create DCIM dir */);
217 }
218
219 // Create a directory named |dir| relative to the test directory.
220 // It does not have a DCIM directory, so RemovableDeviceNotificationsLinux
221 // does not recognizes it as a media directory.
222 FilePath CreateMountPointWithoutDCIMDir(const std::string& dir) {
223 return CreateMountPoint(dir, false /* do not create DCIM dir */);
224 }
225
226 void RemoveDCIMDirFromMountPoint(const std::string& dir) {
227 FilePath dcim(scoped_temp_dir_.path().AppendASCII(dir).AppendASCII(kDCIM));
228 file_util::Delete(dcim, false);
229 }
230
231 base::MockDevicesChangedObserver& observer() {
232 return *mock_devices_changed_observer_;
233 }
234
235 RemovableDeviceNotificationsLinux* notifier() {
236 return notifications_.get();
237 }
238
239 private:
240 // Create a directory named |dir| relative to the test directory.
241 // Set |with_dcim_dir| to true if the created directory will have a "DCIM"
242 // subdirectory.
243 // Returns the full path to the created directory on success, or an empty
244 // path on failure.
245 FilePath CreateMountPoint(const std::string& dir, bool with_dcim_dir) {
246 FilePath return_path(scoped_temp_dir_.path());
247 return_path = return_path.AppendASCII(dir);
248 FilePath path(return_path);
249 if (with_dcim_dir)
250 path = path.AppendASCII(kDCIM);
251 if (!file_util::CreateDirectory(path))
252 return FilePath();
253 return return_path;
254 }
255
256 // Write the test mtab data to |mtab_file_|.
257 // |data| is an array of mtab entries.
258 // |data_size| is the array size of |data|.
259 // |overwrite| specifies whether to overwrite |mtab_file_|.
260 void WriteToMtab(const MtabTestData* data,
261 size_t data_size,
262 bool overwrite) {
263 FILE* file = setmntent(mtab_file_.value().c_str(), overwrite ? "w" : "a");
264 ASSERT_TRUE(file);
265
266 // Due to the glibc *mntent() interface design, which is out of our
267 // control, the mtnent struct has several char* fields, even though
268 // addmntent() does not write to them in the calls below. To make the
269 // compiler happy while avoiding making additional copies of strings,
270 // we just const_cast() the strings' c_str()s.
271 // Assuming addmntent() does not write to the char* fields, this is safe.
272 // It is unlikely the platforms this test suite runs on will have an
273 // addmntent() implementation that does change the char* fields. If that
274 // was ever the case, the test suite will start crashing or failing.
275 mntent entry;
276 static const char kMountOpts[] = "rw";
277 entry.mnt_opts = const_cast<char*>(kMountOpts);
278 entry.mnt_freq = 0;
279 entry.mnt_passno = 0;
280 for (size_t i = 0; i < data_size; ++i) {
281 entry.mnt_fsname = const_cast<char*>(data[i].mount_device.c_str());
282 entry.mnt_dir = const_cast<char*>(data[i].mount_point.c_str());
283 entry.mnt_type = const_cast<char*>(data[i].mount_type.c_str());
284 ASSERT_EQ(0, addmntent(file, &entry));
285 }
286 ASSERT_EQ(1, endmntent(file));
287 }
288
289 // The message loop and file thread to run tests on.
290 MessageLoop message_loop_;
291 content::TestBrowserThread file_thread_;
292
293 // SystemMonitor and DevicesChangedObserver to hook together to test.
294 base::SystemMonitor system_monitor_;
295 scoped_ptr<base::MockDevicesChangedObserver> mock_devices_changed_observer_;
296
297 // Temporary directory for created test data.
298 ScopedTempDir scoped_temp_dir_;
299 // Path to the test mtab file.
300 FilePath mtab_file_;
301
302 scoped_refptr<RemovableDeviceNotificationsLinuxTestWrapper> notifications_;
303
304 DISALLOW_COPY_AND_ASSIGN(RemovableDeviceNotificationLinuxTest);
305 };
306
307 // Simple test case where we attach and detach a media device.
308 TEST_F(RemovableDeviceNotificationLinuxTest, BasicAttachDetach) {
309 testing::Sequence mock_sequence;
310 FilePath test_path = CreateMountPointWithDCIMDir(kMountPointA);
311 ASSERT_FALSE(test_path.empty());
312 MtabTestData test_data[] = {
313 MtabTestData(kDeviceDCIM2, test_path.value(), kValidFS),
314 MtabTestData(kDeviceFixed, kInvalidPath, kValidFS),
315 };
316 // Only |kDeviceDCIM2| should be attached, since |kDeviceFixed| has a bad
317 // path.
318 EXPECT_CALL(observer(),
319 OnRemovableStorageAttached(GetDeviceId(kDeviceDCIM2),
320 GetDeviceName(kDeviceDCIM2),
321 test_path.value()))
322 .InSequence(mock_sequence);
323 AppendToMtabAndRunLoop(test_data, arraysize(test_data));
324
325 // |kDeviceDCIM2| should be detached here.
326 EXPECT_CALL(observer(), OnRemovableStorageDetached(GetDeviceId(kDeviceDCIM2)))
327 .InSequence(mock_sequence);
328 WriteEmptyMtabAndRunLoop();
329 }
330
331 // Only removable devices are recognized.
332 TEST_F(RemovableDeviceNotificationLinuxTest, Removable) {
333 testing::Sequence mock_sequence;
334 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
335 ASSERT_FALSE(test_path_a.empty());
336 MtabTestData test_data1[] = {
337 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
338 };
339 // |kDeviceDCIM1| should be attached as expected.
340 EXPECT_CALL(observer(),
341 OnRemovableStorageAttached(GetDeviceId(kDeviceDCIM1),
342 GetDeviceName(kDeviceDCIM1),
343 test_path_a.value()))
344 .InSequence(mock_sequence);
345 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1));
346
347 // This should do nothing, since |kDeviceFixed| is not removable.
348 FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB);
349 ASSERT_FALSE(test_path_b.empty());
350 MtabTestData test_data2[] = {
351 MtabTestData(kDeviceFixed, test_path_b.value(), kValidFS),
352 };
353 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2));
354
355 // |kDeviceDCIM1| should be detached as expected.
356 EXPECT_CALL(observer(), OnRemovableStorageDetached(GetDeviceId(kDeviceDCIM1)))
357 .InSequence(mock_sequence);
358 WriteEmptyMtabAndRunLoop();
359
360 // |kDeviceNoDCIM| should be attached as expected.
361 EXPECT_CALL(observer(),
362 OnRemovableStorageAttached(GetDeviceId(kDeviceNoDCIM),
363 GetDeviceName(kDeviceNoDCIM),
364 test_path_b.value()))
365 .InSequence(mock_sequence);
366 MtabTestData test_data3[] = {
367 MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
368 };
369 AppendToMtabAndRunLoop(test_data3, arraysize(test_data3));
370
371 // |kDeviceNoDCIM| should be detached as expected.
372 EXPECT_CALL(observer(),
373 OnRemovableStorageDetached(GetDeviceId(kDeviceNoDCIM)))
374 .InSequence(mock_sequence);
375 WriteEmptyMtabAndRunLoop();
376 }
377
378 // More complicated test case with multiple devices on multiple mount points.
379 TEST_F(RemovableDeviceNotificationLinuxTest, SwapMountPoints) {
380 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
381 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB);
382 ASSERT_FALSE(test_path_a.empty());
383 ASSERT_FALSE(test_path_b.empty());
384
385 // Attach two devices. (*'d mounts are those SystemMonitor knows about.)
386 // kDeviceDCIM1 -> kMountPointA *
387 // kDeviceDCIM2 -> kMountPointB *
388 MtabTestData test_data1[] = {
389 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
390 MtabTestData(kDeviceDCIM2, test_path_b.value(), kValidFS),
391 };
392 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
393 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
394 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1));
395
396 // Detach two devices from old mount points and attach the devices at new
397 // mount points.
398 // kDeviceDCIM1 -> kMountPointB *
399 // kDeviceDCIM2 -> kMountPointA *
400 MtabTestData test_data2[] = {
401 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
402 MtabTestData(kDeviceDCIM2, test_path_a.value(), kValidFS),
403 };
404 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
405 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(2);
406 OverwriteMtabAndRunLoop(test_data2, arraysize(test_data2));
407
408 // Detach all devices.
409 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
410 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(2);
411 WriteEmptyMtabAndRunLoop();
412 }
413
414 // More complicated test case with multiple devices on multiple mount points.
415 TEST_F(RemovableDeviceNotificationLinuxTest, MultiDevicesMultiMountPoints) {
416 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
417 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB);
418 ASSERT_FALSE(test_path_a.empty());
419 ASSERT_FALSE(test_path_b.empty());
420
421 // Attach two devices. (*'d mounts are those SystemMonitor knows about.)
422 // kDeviceDCIM1 -> kMountPointA *
423 // kDeviceDCIM2 -> kMountPointB *
424 MtabTestData test_data1[] = {
425 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
426 MtabTestData(kDeviceDCIM2, test_path_b.value(), kValidFS),
427 };
428 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
429 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
430 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1));
431
432 // Attach |kDeviceDCIM1| to |kMountPointB|.
433 // |kDeviceDCIM2| is inaccessible, so it is detached. |kDeviceDCIM1| has been
434 // attached at |kMountPointB|, but is still accessible from |kMountPointA|.
435 // kDeviceDCIM1 -> kMountPointA *
436 // kDeviceDCIM2 -> kMountPointB
437 // kDeviceDCIM1 -> kMountPointB
438 MtabTestData test_data2[] = {
439 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
440 };
441 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
442 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
443 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2));
444
445 // Detach |kDeviceDCIM1| from |kMountPointA|, causing a detach and attach
446 // event.
447 // kDeviceDCIM2 -> kMountPointB
448 // kDeviceDCIM1 -> kMountPointB *
449 MtabTestData test_data3[] = {
450 MtabTestData(kDeviceDCIM2, test_path_b.value(), kValidFS),
451 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
452 };
453 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(1);
454 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
455 OverwriteMtabAndRunLoop(test_data3, arraysize(test_data3));
456
457 // Attach |kDeviceDCIM1| to |kMountPointA|.
458 // kDeviceDCIM2 -> kMountPointB
459 // kDeviceDCIM1 -> kMountPointB *
460 // kDeviceDCIM1 -> kMountPointA
461 MtabTestData test_data4[] = {
462 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
463 };
464 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
465 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
466 AppendToMtabAndRunLoop(test_data4, arraysize(test_data4));
467
468 // Detach |kDeviceDCIM1| from |kMountPointB|.
469 // kDeviceDCIM1 -> kMountPointA *
470 // kDeviceDCIM2 -> kMountPointB *
471 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
472 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
473 OverwriteMtabAndRunLoop(test_data1, arraysize(test_data1));
474
475 // Detach all devices.
476 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
477 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(2);
478 WriteEmptyMtabAndRunLoop();
479 }
480
481 TEST_F(RemovableDeviceNotificationLinuxTest,
482 MultipleMountPointsWithNonDCIMDevices) {
483 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
484 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB);
485 ASSERT_FALSE(test_path_a.empty());
486 ASSERT_FALSE(test_path_b.empty());
487
488 // Attach to one first. (*'d mounts are those SystemMonitor knows about.)
489 // kDeviceDCIM1 -> kMountPointA *
490 MtabTestData test_data1[] = {
491 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
492 };
493 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(1);
494 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
495 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1));
496
497 // Attach |kDeviceDCIM1| to |kMountPointB|.
498 // kDeviceDCIM1 -> kMountPointA *
499 // kDeviceDCIM1 -> kMountPointB
500 MtabTestData test_data2[] = {
501 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
502 };
503 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
504 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
505 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2));
506
507 // Attach |kDeviceFixed| (a non-removable device) to |kMountPointA|.
508 // kDeviceDCIM1 -> kMountPointA
509 // kDeviceDCIM1 -> kMountPointB *
510 // kDeviceFixed -> kMountPointA
511 MtabTestData test_data3[] = {
512 MtabTestData(kDeviceFixed, test_path_a.value(), kValidFS),
513 };
514 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(1);
515 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
516 RemoveDCIMDirFromMountPoint(kMountPointA);
517 AppendToMtabAndRunLoop(test_data3, arraysize(test_data3));
518
519 // Detach |kDeviceFixed|.
520 // kDeviceDCIM1 -> kMountPointA
521 // kDeviceDCIM1 -> kMountPointB *
522 MtabTestData test_data4[] = {
523 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
524 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
525 };
526 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
527 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
528 CreateMountPointWithDCIMDir(kMountPointA);
529 OverwriteMtabAndRunLoop(test_data4, arraysize(test_data4));
530
531 // Attach |kDeviceNoDCIM| (a non-DCIM device) to |kMountPointB|.
532 // kDeviceDCIM1 -> kMountPointA *
533 // kDeviceDCIM1 -> kMountPointB
534 // kDeviceNoDCIM -> kMountPointB *
535 MtabTestData test_data5[] = {
536 MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
537 };
538 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
539 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
540 file_util::Delete(test_path_b.Append("DCIM"), false);
541 AppendToMtabAndRunLoop(test_data5, arraysize(test_data5));
542
543 // Detach |kDeviceNoDCIM|.
544 // kDeviceDCIM1 -> kMountPointA *
545 // kDeviceDCIM1 -> kMountPointB
546 MtabTestData test_data6[] = {
547 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
548 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
549 };
550 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
551 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
552 CreateMountPointWithDCIMDir(kMountPointB);
553 OverwriteMtabAndRunLoop(test_data6, arraysize(test_data6));
554
555 // Detach |kDeviceDCIM1| from |kMountPointB|.
556 // kDeviceDCIM1 -> kMountPointA *
557 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
558 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
559 OverwriteMtabAndRunLoop(test_data1, arraysize(test_data1));
560
561 // Detach all devices.
562 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
563 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
564 WriteEmptyMtabAndRunLoop();
565 }
566
567 TEST_F(RemovableDeviceNotificationLinuxTest, MountLookUp) {
568 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
569 FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB);
570 FilePath test_path_c = CreateMountPointWithoutDCIMDir(kMountPointC);
571 ASSERT_FALSE(test_path_a.empty());
572 ASSERT_FALSE(test_path_b.empty());
573 ASSERT_FALSE(test_path_c.empty());
574
575 // Attach to one first. (*'d mounts are those SystemMonitor knows about.)
576 // kDeviceDCIM1 -> kMountPointA *
577 // kDeviceNoDCIM -> kMountPointB *
578 // kDeviceFixed -> kMountPointC
579 MtabTestData test_data1[] = {
580 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
581 MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
582 MtabTestData(kDeviceFixed, test_path_c.value(), kValidFS),
583 };
584 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
585 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
586 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1));
587
588 EXPECT_EQ(test_path_a,
589 notifier()->GetDeviceMountPoint(GetDeviceId(kDeviceDCIM1)));
590 EXPECT_EQ(test_path_b,
591 notifier()->GetDeviceMountPoint(GetDeviceId(kDeviceNoDCIM)));
592 EXPECT_EQ(test_path_c,
593 notifier()->GetDeviceMountPoint(GetDeviceId(kDeviceFixed)));
594 EXPECT_EQ(FilePath(),
595 notifier()->GetDeviceMountPoint(GetDeviceId(kInvalidDevice)));
596
597 // Make |kDeviceDCIM1| mounted in multiple places.
598 // kDeviceDCIM1 -> kMountPointA *
599 // kDeviceDCIM1 -> kMountPointB
600 // kDeviceDCIM1 -> kMountPointC
601 MtabTestData test_data2[] = {
602 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
603 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
604 MtabTestData(kDeviceDCIM1, test_path_c.value(), kValidFS),
605 };
606 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
607 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
608 // Add DCIM dirs.
609 CreateMountPointWithDCIMDir(kMountPointB);
610 CreateMountPointWithDCIMDir(kMountPointC);
611 OverwriteMtabAndRunLoop(test_data2, arraysize(test_data2));
612
613 EXPECT_EQ(test_path_a,
614 notifier()->GetDeviceMountPoint(GetDeviceId(kDeviceDCIM1)));
615
616 // Unmount |kDeviceDCIM1| from |kMountPointA|.
617 // kDeviceDCIM1 -> kMountPointB *
618 // kDeviceDCIM1 -> kMountPointC
619 // Either |kMountPointB| or |kMountPointC| is a valid new default, but
620 // it turns out that it will be B.
621 MtabTestData test_data3[] = {
622 MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
623 };
624 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(1);
625 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
626 OverwriteMtabAndRunLoop(test_data3, arraysize(test_data3));
627
628 EXPECT_EQ(test_path_b,
629 notifier()->GetDeviceMountPoint(GetDeviceId(kDeviceDCIM1)));
630
631 // Mount a non-removable device in multiple places.
632 // kDeviceFixed -> kMountPointA
633 // kDeviceFixed -> kMountPointB
634 // kDeviceFixed -> kMountPointC
635 MtabTestData test_data4[] = {
636 MtabTestData(kDeviceFixed, test_path_a.value(), kValidFS),
637 MtabTestData(kDeviceFixed, test_path_b.value(), kValidFS),
638 MtabTestData(kDeviceFixed, test_path_c.value(), kValidFS),
639 };
640 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
641 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
642 // Remove DCIM dirs.
643 RemoveDCIMDirFromMountPoint(kMountPointA);
644 RemoveDCIMDirFromMountPoint(kMountPointB);
645 RemoveDCIMDirFromMountPoint(kMountPointC);
646 OverwriteMtabAndRunLoop(test_data4, arraysize(test_data4));
647
648 // Any of the mount points would be valid.
649 EXPECT_EQ(test_path_a.value(),
650 notifier()->GetDeviceMountPoint(GetDeviceId(kDeviceFixed)).value());
651 }
652
653 TEST_F(RemovableDeviceNotificationLinuxTest, DeviceLookUp) {
654 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
655 FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB);
656 FilePath test_path_c = CreateMountPointWithoutDCIMDir(kMountPointC);
657 ASSERT_FALSE(test_path_a.empty());
658 ASSERT_FALSE(test_path_b.empty());
659 ASSERT_FALSE(test_path_c.empty());
660
661 // Attach to one first. (*'d mounts are those SystemMonitor knows about.)
662 // kDeviceDCIM1 -> kMountPointA *
663 // kDeviceNoDCIM -> kMountPointB *
664 // kDeviceFixed -> kMountPointC
665 MtabTestData test_data1[] = {
666 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
667 MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
668 MtabTestData(kDeviceFixed, test_path_c.value(), kValidFS),
669 };
670 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(2);
671 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
672 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1));
673
674 base::SystemMonitor::RemovableStorageInfo device_info;
675 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(test_path_a, &device_info));
676 EXPECT_EQ(GetDeviceId(kDeviceDCIM1), device_info.device_id);
677 EXPECT_EQ(test_path_a.value(), device_info.location);
678 EXPECT_EQ(GetDeviceName(kDeviceDCIM1), device_info.name);
679
680 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(test_path_b, &device_info));
681 EXPECT_EQ(GetDeviceId(kDeviceNoDCIM), device_info.device_id);
682 EXPECT_EQ(test_path_b.value(), device_info.location);
683 EXPECT_EQ(GetDeviceName(kDeviceNoDCIM), device_info.name);
684
685 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(test_path_c, &device_info));
686 EXPECT_EQ(GetDeviceId(kDeviceFixed), device_info.device_id);
687 EXPECT_EQ(test_path_c.value(), device_info.location);
688 EXPECT_EQ(GetDeviceName(kDeviceFixed), device_info.name);
689
690 // An invalid path.
691 EXPECT_FALSE(notifier()->GetDeviceInfoForPath(FilePath(kInvalidPath), NULL));
692
693 // Test filling in of the mount point.
694 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(
695 test_path_a.Append("some/other/path"), &device_info));
696 EXPECT_EQ(GetDeviceId(kDeviceDCIM1), device_info.device_id);
697 EXPECT_EQ(test_path_a.value(), device_info.location);
698 EXPECT_EQ(GetDeviceName(kDeviceDCIM1), device_info.name);
699
700 // One device attached at multiple points.
701 // kDeviceDCIM1 -> kMountPointA *
702 // kDeviceFixed -> kMountPointB
703 // kDeviceFixed -> kMountPointC
704 MtabTestData test_data2[] = {
705 MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
706 MtabTestData(kDeviceFixed, test_path_b.value(), kValidFS),
707 MtabTestData(kDeviceFixed, test_path_c.value(), kValidFS),
708 };
709 EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
710 EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(1);
711 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2));
712
713 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(test_path_a, &device_info));
714 EXPECT_EQ(GetDeviceId(kDeviceDCIM1), device_info.device_id);
715
716 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(test_path_b, &device_info));
717 EXPECT_EQ(GetDeviceId(kDeviceFixed), device_info.device_id);
718
719 EXPECT_TRUE(notifier()->GetDeviceInfoForPath(test_path_c, &device_info));
720 EXPECT_EQ(GetDeviceId(kDeviceFixed), device_info.device_id);
721 }
722
723 } // namespace
724
725 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698