1 // Copyright 2014 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.
5 // StorageMonitorLinux unit tests.
7 #include "components/storage_monitor/storage_monitor_linux.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/run_loop.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "components/storage_monitor/mock_removable_storage_observer.h"
22 #include "components/storage_monitor/removable_device_constants.h"
23 #include "components/storage_monitor/storage_info.h"
24 #include "components/storage_monitor/storage_monitor.h"
25 #include "components/storage_monitor/test_media_transfer_protocol_manager_linux.h"
26 #include "components/storage_monitor/test_storage_monitor.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 namespace storage_monitor
{
34 const char kValidFS
[] = "vfat";
35 const char kInvalidFS
[] = "invalidfs";
37 const char kInvalidPath
[] = "invalid path does not exist";
39 const char kDeviceDCIM1
[] = "d1";
40 const char kDeviceDCIM2
[] = "d2";
41 const char kDeviceDCIM3
[] = "d3";
42 const char kDeviceNoDCIM
[] = "d4";
43 const char kDeviceFixed
[] = "d5";
45 const char kInvalidDevice
[] = "invalid_device";
47 const char kMountPointA
[] = "mnt_a";
48 const char kMountPointB
[] = "mnt_b";
49 const char kMountPointC
[] = "mnt_c";
51 struct TestDeviceData
{
52 const char* device_path
;
53 const char* unique_id
;
54 StorageInfo::Type type
;
55 uint64 partition_size_in_bytes
;
58 const TestDeviceData kTestDeviceData
[] = {
59 { kDeviceDCIM1
, "UUID:FFF0-000F",
60 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
, 88788 },
61 { kDeviceDCIM2
, "VendorModelSerial:ComName:Model2010:8989",
62 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
64 { kDeviceDCIM3
, "VendorModelSerial:::WEM319X792",
65 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
, 22837 },
66 { kDeviceNoDCIM
, "UUID:ABCD-1234",
67 StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
, 512 },
68 { kDeviceFixed
, "UUID:743A-2349",
69 StorageInfo::FIXED_MASS_STORAGE
, 17282 },
72 scoped_ptr
<StorageInfo
> GetDeviceInfo(const base::FilePath
& device_path
,
73 const base::FilePath
& mount_point
) {
74 bool device_found
= false;
76 for (; i
< arraysize(kTestDeviceData
); i
++) {
77 if (device_path
.value() == kTestDeviceData
[i
].device_path
) {
83 scoped_ptr
<StorageInfo
> storage_info
;
86 return storage_info
.Pass();
89 StorageInfo::Type type
= kTestDeviceData
[i
].type
;
90 storage_info
.reset(new StorageInfo(
91 StorageInfo::MakeDeviceId(type
, kTestDeviceData
[i
].unique_id
),
93 base::ASCIIToUTF16("volume label"),
94 base::ASCIIToUTF16("vendor name"),
95 base::ASCIIToUTF16("model name"),
96 kTestDeviceData
[i
].partition_size_in_bytes
));
97 return storage_info
.Pass();
100 uint64
GetDevicePartitionSize(const std::string
& device
) {
101 for (size_t i
= 0; i
< arraysize(kTestDeviceData
); ++i
) {
102 if (device
== kTestDeviceData
[i
].device_path
)
103 return kTestDeviceData
[i
].partition_size_in_bytes
;
108 std::string
GetDeviceId(const std::string
& device
) {
109 for (size_t i
= 0; i
< arraysize(kTestDeviceData
); ++i
) {
110 if (device
== kTestDeviceData
[i
].device_path
) {
111 return StorageInfo::MakeDeviceId(kTestDeviceData
[i
].type
,
112 kTestDeviceData
[i
].unique_id
);
115 if (device
== kInvalidDevice
) {
116 return StorageInfo::MakeDeviceId(StorageInfo::FIXED_MASS_STORAGE
,
119 return std::string();
122 class TestStorageMonitorLinux
: public StorageMonitorLinux
{
124 explicit TestStorageMonitorLinux(const base::FilePath
& path
)
125 : StorageMonitorLinux(path
) {
126 SetMediaTransferProtocolManagerForTest(
127 new TestMediaTransferProtocolManagerLinux());
128 SetGetDeviceInfoCallbackForTest(base::Bind(&GetDeviceInfo
));
130 ~TestStorageMonitorLinux() override
{}
134 const MtabWatcherLinux::MountPointDeviceMap
& new_mtab
) override
{
135 StorageMonitorLinux::UpdateMtab(new_mtab
);
136 base::ThreadTaskRunnerHandle::Get()->PostTask(
137 FROM_HERE
, base::MessageLoop::QuitClosure());
140 DISALLOW_COPY_AND_ASSIGN(TestStorageMonitorLinux
);
143 class StorageMonitorLinuxTest
: public testing::Test
{
145 struct MtabTestData
{
146 MtabTestData(const std::string
& mount_device
,
147 const std::string
& mount_point
,
148 const std::string
& mount_type
)
149 : mount_device(mount_device
),
150 mount_point(mount_point
),
151 mount_type(mount_type
) {
154 const std::string mount_device
;
155 const std::string mount_point
;
156 const std::string mount_type
;
159 StorageMonitorLinuxTest()
160 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
) {}
161 ~StorageMonitorLinuxTest() override
{}
164 void SetUp() override
{
165 // Create and set up a temp dir with files for the test.
166 ASSERT_TRUE(scoped_temp_dir_
.CreateUniqueTempDir());
167 base::FilePath test_dir
= scoped_temp_dir_
.path().AppendASCII("test_etc");
168 ASSERT_TRUE(base::CreateDirectory(test_dir
));
169 mtab_file_
= test_dir
.AppendASCII("test_mtab");
170 MtabTestData initial_test_data
[] = {
171 MtabTestData("dummydevice", "dummydir", kInvalidFS
),
173 WriteToMtab(initial_test_data
,
174 arraysize(initial_test_data
),
175 true /* overwrite */);
177 monitor_
.reset(new TestStorageMonitorLinux(mtab_file_
));
179 mock_storage_observer_
.reset(new MockRemovableStorageObserver
);
180 monitor_
->AddObserver(mock_storage_observer_
.get());
183 base::RunLoop().RunUntilIdle();
186 void TearDown() override
{
187 base::RunLoop().RunUntilIdle();
188 monitor_
->RemoveObserver(mock_storage_observer_
.get());
189 base::RunLoop().RunUntilIdle();
191 // Linux storage monitor must be destroyed on the UI thread, so do it here.
195 // Append mtab entries from the |data| array of size |data_size| to the mtab
196 // file, and run the message loop.
197 void AppendToMtabAndRunLoop(const MtabTestData
* data
, size_t data_size
) {
198 WriteToMtab(data
, data_size
, false /* do not overwrite */);
199 base::RunLoop().Run();
202 // Overwrite the mtab file with mtab entries from the |data| array of size
203 // |data_size|, and run the message loop.
204 void OverwriteMtabAndRunLoop(const MtabTestData
* data
, size_t data_size
) {
205 WriteToMtab(data
, data_size
, true /* overwrite */);
206 base::RunLoop().Run();
209 // Simplied version of OverwriteMtabAndRunLoop() that just deletes all the
210 // entries in the mtab file.
211 void WriteEmptyMtabAndRunLoop() {
212 OverwriteMtabAndRunLoop(NULL
, // No data.
213 0); // No data length.
216 // Create a directory named |dir| relative to the test directory.
217 // It has a DCIM directory, so StorageMonitorLinux recognizes it as a media
219 base::FilePath
CreateMountPointWithDCIMDir(const std::string
& dir
) {
220 return CreateMountPoint(dir
, true /* create DCIM dir */);
223 // Create a directory named |dir| relative to the test directory.
224 // It does not have a DCIM directory, so StorageMonitorLinux does not
225 // recognize it as a media directory.
226 base::FilePath
CreateMountPointWithoutDCIMDir(const std::string
& dir
) {
227 return CreateMountPoint(dir
, false /* do not create DCIM dir */);
230 void RemoveDCIMDirFromMountPoint(const std::string
& dir
) {
231 base::FilePath dcim
=
232 scoped_temp_dir_
.path().AppendASCII(dir
).Append(kDCIMDirectoryName
);
233 base::DeleteFile(dcim
, false);
236 MockRemovableStorageObserver
& observer() {
237 return *mock_storage_observer_
;
240 StorageMonitor
* notifier() {
241 return monitor_
.get();
244 uint64
GetStorageSize(const base::FilePath
& path
) {
246 if (!notifier()->GetStorageInfoForPath(path
, &info
))
249 return info
.total_size_in_bytes();
253 // Create a directory named |dir| relative to the test directory.
254 // Set |with_dcim_dir| to true if the created directory will have a "DCIM"
256 // Returns the full path to the created directory on success, or an empty
258 base::FilePath
CreateMountPoint(const std::string
& dir
, bool with_dcim_dir
) {
259 base::FilePath
return_path(scoped_temp_dir_
.path());
260 return_path
= return_path
.AppendASCII(dir
);
261 base::FilePath
path(return_path
);
263 path
= path
.Append(kDCIMDirectoryName
);
264 if (!base::CreateDirectory(path
))
265 return base::FilePath();
269 // Write the test mtab data to |mtab_file_|.
270 // |data| is an array of mtab entries.
271 // |data_size| is the array size of |data|.
272 // |overwrite| specifies whether to overwrite |mtab_file_|.
273 void WriteToMtab(const MtabTestData
* data
,
276 FILE* file
= setmntent(mtab_file_
.value().c_str(), overwrite
? "w" : "a");
279 // Due to the glibc *mntent() interface design, which is out of our
280 // control, the mtnent struct has several char* fields, even though
281 // addmntent() does not write to them in the calls below. To make the
282 // compiler happy while avoiding making additional copies of strings,
283 // we just const_cast() the strings' c_str()s.
284 // Assuming addmntent() does not write to the char* fields, this is safe.
285 // It is unlikely the platforms this test suite runs on will have an
286 // addmntent() implementation that does change the char* fields. If that
287 // was ever the case, the test suite will start crashing or failing.
289 static const char kMountOpts
[] = "rw";
290 entry
.mnt_opts
= const_cast<char*>(kMountOpts
);
292 entry
.mnt_passno
= 0;
293 for (size_t i
= 0; i
< data_size
; ++i
) {
294 entry
.mnt_fsname
= const_cast<char*>(data
[i
].mount_device
.c_str());
295 entry
.mnt_dir
= const_cast<char*>(data
[i
].mount_point
.c_str());
296 entry
.mnt_type
= const_cast<char*>(data
[i
].mount_type
.c_str());
297 ASSERT_EQ(0, addmntent(file
, &entry
));
299 ASSERT_EQ(1, endmntent(file
));
302 content::TestBrowserThreadBundle thread_bundle_
;
304 scoped_ptr
<MockRemovableStorageObserver
> mock_storage_observer_
;
306 // Temporary directory for created test data.
307 base::ScopedTempDir scoped_temp_dir_
;
308 // Path to the test mtab file.
309 base::FilePath mtab_file_
;
311 scoped_ptr
<TestStorageMonitorLinux
> monitor_
;
313 DISALLOW_COPY_AND_ASSIGN(StorageMonitorLinuxTest
);
316 // Simple test case where we attach and detach a media device.
317 // http://crbug.com/526252 flaky
318 TEST_F(StorageMonitorLinuxTest
, DISABLED_BasicAttachDetach
) {
319 base::FilePath test_path
= CreateMountPointWithDCIMDir(kMountPointA
);
320 ASSERT_FALSE(test_path
.empty());
321 MtabTestData test_data
[] = {
322 MtabTestData(kDeviceDCIM2
, test_path
.value(), kValidFS
),
323 MtabTestData(kDeviceFixed
, kInvalidPath
, kValidFS
),
325 // Only |kDeviceDCIM2| should be attached, since |kDeviceFixed| has a bad
327 AppendToMtabAndRunLoop(test_data
, arraysize(test_data
));
329 EXPECT_EQ(1, observer().attach_calls());
330 EXPECT_EQ(0, observer().detach_calls());
331 EXPECT_EQ(GetDeviceId(kDeviceDCIM2
), observer().last_attached().device_id());
332 EXPECT_EQ(test_path
.value(), observer().last_attached().location());
334 // |kDeviceDCIM2| should be detached here.
335 WriteEmptyMtabAndRunLoop();
336 EXPECT_EQ(1, observer().attach_calls());
337 EXPECT_EQ(1, observer().detach_calls());
338 EXPECT_EQ(GetDeviceId(kDeviceDCIM2
), observer().last_detached().device_id());
341 // Only removable devices are recognized.
342 // http://crbug.com/526252 flaky
343 TEST_F(StorageMonitorLinuxTest
, DISABLED_Removable
) {
344 base::FilePath test_path_a
= CreateMountPointWithDCIMDir(kMountPointA
);
345 ASSERT_FALSE(test_path_a
.empty());
346 MtabTestData test_data1
[] = {
347 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
349 // |kDeviceDCIM1| should be attached as expected.
350 AppendToMtabAndRunLoop(test_data1
, arraysize(test_data1
));
352 EXPECT_EQ(1, observer().attach_calls());
353 EXPECT_EQ(0, observer().detach_calls());
354 EXPECT_EQ(GetDeviceId(kDeviceDCIM1
), observer().last_attached().device_id());
355 EXPECT_EQ(test_path_a
.value(), observer().last_attached().location());
357 // This should do nothing, since |kDeviceFixed| is not removable.
358 base::FilePath test_path_b
= CreateMountPointWithoutDCIMDir(kMountPointB
);
359 ASSERT_FALSE(test_path_b
.empty());
360 MtabTestData test_data2
[] = {
361 MtabTestData(kDeviceFixed
, test_path_b
.value(), kValidFS
),
363 AppendToMtabAndRunLoop(test_data2
, arraysize(test_data2
));
364 EXPECT_EQ(1, observer().attach_calls());
365 EXPECT_EQ(0, observer().detach_calls());
367 // |kDeviceDCIM1| should be detached as expected.
368 WriteEmptyMtabAndRunLoop();
369 EXPECT_EQ(1, observer().attach_calls());
370 EXPECT_EQ(1, observer().detach_calls());
371 EXPECT_EQ(GetDeviceId(kDeviceDCIM1
), observer().last_detached().device_id());
373 // |kDeviceNoDCIM| should be attached as expected.
374 MtabTestData test_data3
[] = {
375 MtabTestData(kDeviceNoDCIM
, test_path_b
.value(), kValidFS
),
377 AppendToMtabAndRunLoop(test_data3
, arraysize(test_data3
));
378 EXPECT_EQ(2, observer().attach_calls());
379 EXPECT_EQ(1, observer().detach_calls());
380 EXPECT_EQ(GetDeviceId(kDeviceNoDCIM
), observer().last_attached().device_id());
381 EXPECT_EQ(test_path_b
.value(), observer().last_attached().location());
383 // |kDeviceNoDCIM| should be detached as expected.
384 WriteEmptyMtabAndRunLoop();
385 EXPECT_EQ(2, observer().attach_calls());
386 EXPECT_EQ(2, observer().detach_calls());
387 EXPECT_EQ(GetDeviceId(kDeviceNoDCIM
), observer().last_detached().device_id());
390 // More complicated test case with multiple devices on multiple mount points.
391 // http://crbug.com/526252 flaky
392 TEST_F(StorageMonitorLinuxTest
, DISABLED_SwapMountPoints
) {
393 base::FilePath test_path_a
= CreateMountPointWithDCIMDir(kMountPointA
);
394 base::FilePath test_path_b
= CreateMountPointWithDCIMDir(kMountPointB
);
395 ASSERT_FALSE(test_path_a
.empty());
396 ASSERT_FALSE(test_path_b
.empty());
398 // Attach two devices.
399 // (*'d mounts are those StorageMonitor knows about.)
400 // kDeviceDCIM1 -> kMountPointA *
401 // kDeviceDCIM2 -> kMountPointB *
402 MtabTestData test_data1
[] = {
403 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
404 MtabTestData(kDeviceDCIM2
, test_path_b
.value(), kValidFS
),
406 AppendToMtabAndRunLoop(test_data1
, arraysize(test_data1
));
407 EXPECT_EQ(2, observer().attach_calls());
408 EXPECT_EQ(0, observer().detach_calls());
410 // Detach two devices from old mount points and attach the devices at new
412 // kDeviceDCIM1 -> kMountPointB *
413 // kDeviceDCIM2 -> kMountPointA *
414 MtabTestData test_data2
[] = {
415 MtabTestData(kDeviceDCIM1
, test_path_b
.value(), kValidFS
),
416 MtabTestData(kDeviceDCIM2
, test_path_a
.value(), kValidFS
),
418 OverwriteMtabAndRunLoop(test_data2
, arraysize(test_data2
));
419 EXPECT_EQ(4, observer().attach_calls());
420 EXPECT_EQ(2, observer().detach_calls());
422 // Detach all devices.
423 WriteEmptyMtabAndRunLoop();
424 EXPECT_EQ(4, observer().attach_calls());
425 EXPECT_EQ(4, observer().detach_calls());
428 // More complicated test case with multiple devices on multiple mount points.
429 // http://crbug.com/526252 flaky
430 TEST_F(StorageMonitorLinuxTest
, DISABLED_MultiDevicesMultiMountPoints
) {
431 base::FilePath test_path_a
= CreateMountPointWithDCIMDir(kMountPointA
);
432 base::FilePath test_path_b
= CreateMountPointWithDCIMDir(kMountPointB
);
433 ASSERT_FALSE(test_path_a
.empty());
434 ASSERT_FALSE(test_path_b
.empty());
436 // Attach two devices.
437 // (*'d mounts are those StorageMonitor knows about.)
438 // kDeviceDCIM1 -> kMountPointA *
439 // kDeviceDCIM2 -> kMountPointB *
440 MtabTestData test_data1
[] = {
441 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
442 MtabTestData(kDeviceDCIM2
, test_path_b
.value(), kValidFS
),
444 AppendToMtabAndRunLoop(test_data1
, arraysize(test_data1
));
445 EXPECT_EQ(2, observer().attach_calls());
446 EXPECT_EQ(0, observer().detach_calls());
448 // Attach |kDeviceDCIM1| to |kMountPointB|.
449 // |kDeviceDCIM2| is inaccessible, so it is detached. |kDeviceDCIM1| has been
450 // attached at |kMountPointB|, but is still accessible from |kMountPointA|.
451 // kDeviceDCIM1 -> kMountPointA *
452 // kDeviceDCIM2 -> kMountPointB
453 // kDeviceDCIM1 -> kMountPointB
454 MtabTestData test_data2
[] = {
455 MtabTestData(kDeviceDCIM1
, test_path_b
.value(), kValidFS
),
457 AppendToMtabAndRunLoop(test_data2
, arraysize(test_data2
));
458 EXPECT_EQ(2, observer().attach_calls());
459 EXPECT_EQ(1, observer().detach_calls());
461 // Detach |kDeviceDCIM1| from |kMountPointA|, causing a detach and attach
463 // kDeviceDCIM2 -> kMountPointB
464 // kDeviceDCIM1 -> kMountPointB *
465 MtabTestData test_data3
[] = {
466 MtabTestData(kDeviceDCIM2
, test_path_b
.value(), kValidFS
),
467 MtabTestData(kDeviceDCIM1
, test_path_b
.value(), kValidFS
),
469 OverwriteMtabAndRunLoop(test_data3
, arraysize(test_data3
));
470 EXPECT_EQ(3, observer().attach_calls());
471 EXPECT_EQ(2, observer().detach_calls());
473 // Attach |kDeviceDCIM1| to |kMountPointA|.
474 // kDeviceDCIM2 -> kMountPointB
475 // kDeviceDCIM1 -> kMountPointB *
476 // kDeviceDCIM1 -> kMountPointA
477 MtabTestData test_data4
[] = {
478 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
480 AppendToMtabAndRunLoop(test_data4
, arraysize(test_data4
));
481 EXPECT_EQ(3, observer().attach_calls());
482 EXPECT_EQ(2, observer().detach_calls());
484 // Detach |kDeviceDCIM1| from |kMountPointB|.
485 // kDeviceDCIM1 -> kMountPointA *
486 // kDeviceDCIM2 -> kMountPointB *
487 OverwriteMtabAndRunLoop(test_data1
, arraysize(test_data1
));
488 EXPECT_EQ(5, observer().attach_calls());
489 EXPECT_EQ(3, observer().detach_calls());
491 // Detach all devices.
492 WriteEmptyMtabAndRunLoop();
493 EXPECT_EQ(5, observer().attach_calls());
494 EXPECT_EQ(5, observer().detach_calls());
497 // http://crbug.com/526252 flaky
498 TEST_F(StorageMonitorLinuxTest
,
499 DISABLED_MultipleMountPointsWithNonDCIMDevices
) {
500 base::FilePath test_path_a
= CreateMountPointWithDCIMDir(kMountPointA
);
501 base::FilePath test_path_b
= CreateMountPointWithDCIMDir(kMountPointB
);
502 ASSERT_FALSE(test_path_a
.empty());
503 ASSERT_FALSE(test_path_b
.empty());
505 // Attach to one first.
506 // (*'d mounts are those StorageMonitor knows about.)
507 // kDeviceDCIM1 -> kMountPointA *
508 MtabTestData test_data1
[] = {
509 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
511 AppendToMtabAndRunLoop(test_data1
, arraysize(test_data1
));
512 EXPECT_EQ(1, observer().attach_calls());
513 EXPECT_EQ(0, observer().detach_calls());
515 // Attach |kDeviceDCIM1| to |kMountPointB|.
516 // kDeviceDCIM1 -> kMountPointA *
517 // kDeviceDCIM1 -> kMountPointB
518 MtabTestData test_data2
[] = {
519 MtabTestData(kDeviceDCIM1
, test_path_b
.value(), kValidFS
),
521 AppendToMtabAndRunLoop(test_data2
, arraysize(test_data2
));
522 EXPECT_EQ(1, observer().attach_calls());
523 EXPECT_EQ(0, observer().detach_calls());
525 // Attach |kDeviceFixed| (a non-removable device) to |kMountPointA|.
526 // kDeviceDCIM1 -> kMountPointA
527 // kDeviceDCIM1 -> kMountPointB *
528 // kDeviceFixed -> kMountPointA
529 MtabTestData test_data3
[] = {
530 MtabTestData(kDeviceFixed
, test_path_a
.value(), kValidFS
),
532 RemoveDCIMDirFromMountPoint(kMountPointA
);
533 AppendToMtabAndRunLoop(test_data3
, arraysize(test_data3
));
534 EXPECT_EQ(2, observer().attach_calls());
535 EXPECT_EQ(1, observer().detach_calls());
537 // Detach |kDeviceFixed|.
538 // kDeviceDCIM1 -> kMountPointA
539 // kDeviceDCIM1 -> kMountPointB *
540 MtabTestData test_data4
[] = {
541 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
542 MtabTestData(kDeviceDCIM1
, test_path_b
.value(), kValidFS
),
544 CreateMountPointWithDCIMDir(kMountPointA
);
545 OverwriteMtabAndRunLoop(test_data4
, arraysize(test_data4
));
546 EXPECT_EQ(2, observer().attach_calls());
547 EXPECT_EQ(1, observer().detach_calls());
549 // Attach |kDeviceNoDCIM| (a non-DCIM device) to |kMountPointB|.
550 // kDeviceDCIM1 -> kMountPointA *
551 // kDeviceDCIM1 -> kMountPointB
552 // kDeviceNoDCIM -> kMountPointB *
553 MtabTestData test_data5
[] = {
554 MtabTestData(kDeviceNoDCIM
, test_path_b
.value(), kValidFS
),
556 base::DeleteFile(test_path_b
.Append(kDCIMDirectoryName
), false);
557 AppendToMtabAndRunLoop(test_data5
, arraysize(test_data5
));
558 EXPECT_EQ(4, observer().attach_calls());
559 EXPECT_EQ(2, observer().detach_calls());
561 // Detach |kDeviceNoDCIM|.
562 // kDeviceDCIM1 -> kMountPointA *
563 // kDeviceDCIM1 -> kMountPointB
564 MtabTestData test_data6
[] = {
565 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
566 MtabTestData(kDeviceDCIM1
, test_path_b
.value(), kValidFS
),
568 CreateMountPointWithDCIMDir(kMountPointB
);
569 OverwriteMtabAndRunLoop(test_data6
, arraysize(test_data6
));
570 EXPECT_EQ(4, observer().attach_calls());
571 EXPECT_EQ(3, observer().detach_calls());
573 // Detach |kDeviceDCIM1| from |kMountPointB|.
574 // kDeviceDCIM1 -> kMountPointA *
575 OverwriteMtabAndRunLoop(test_data1
, arraysize(test_data1
));
576 EXPECT_EQ(4, observer().attach_calls());
577 EXPECT_EQ(3, observer().detach_calls());
579 // Detach all devices.
580 WriteEmptyMtabAndRunLoop();
581 EXPECT_EQ(4, observer().attach_calls());
582 EXPECT_EQ(4, observer().detach_calls());
585 // http://crbug.com/526252 flaky
586 TEST_F(StorageMonitorLinuxTest
, DISABLED_DeviceLookUp
) {
587 base::FilePath test_path_a
= CreateMountPointWithDCIMDir(kMountPointA
);
588 base::FilePath test_path_b
= CreateMountPointWithoutDCIMDir(kMountPointB
);
589 base::FilePath test_path_c
= CreateMountPointWithoutDCIMDir(kMountPointC
);
590 ASSERT_FALSE(test_path_a
.empty());
591 ASSERT_FALSE(test_path_b
.empty());
592 ASSERT_FALSE(test_path_c
.empty());
594 // Attach to one first.
595 // (starred mounts are those StorageMonitor knows about.)
596 // kDeviceDCIM1 -> kMountPointA *
597 // kDeviceNoDCIM -> kMountPointB *
598 // kDeviceFixed -> kMountPointC
599 MtabTestData test_data1
[] = {
600 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
601 MtabTestData(kDeviceNoDCIM
, test_path_b
.value(), kValidFS
),
602 MtabTestData(kDeviceFixed
, test_path_c
.value(), kValidFS
),
604 AppendToMtabAndRunLoop(test_data1
, arraysize(test_data1
));
605 EXPECT_EQ(2, observer().attach_calls());
606 EXPECT_EQ(0, observer().detach_calls());
608 StorageInfo device_info
;
609 EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_a
, &device_info
));
610 EXPECT_EQ(GetDeviceId(kDeviceDCIM1
), device_info
.device_id());
611 EXPECT_EQ(test_path_a
.value(), device_info
.location());
612 EXPECT_EQ(88788ULL, device_info
.total_size_in_bytes());
613 EXPECT_EQ(base::ASCIIToUTF16("volume label"), device_info
.storage_label());
614 EXPECT_EQ(base::ASCIIToUTF16("vendor name"), device_info
.vendor_name());
615 EXPECT_EQ(base::ASCIIToUTF16("model name"), device_info
.model_name());
617 EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_b
, &device_info
));
618 EXPECT_EQ(GetDeviceId(kDeviceNoDCIM
), device_info
.device_id());
619 EXPECT_EQ(test_path_b
.value(), device_info
.location());
621 EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_c
, &device_info
));
622 EXPECT_EQ(GetDeviceId(kDeviceFixed
), device_info
.device_id());
623 EXPECT_EQ(test_path_c
.value(), device_info
.location());
626 EXPECT_FALSE(notifier()->GetStorageInfoForPath(base::FilePath(kInvalidPath
),
629 // Test filling in of the mount point.
631 notifier()->GetStorageInfoForPath(test_path_a
.Append("some/other/path"),
633 EXPECT_EQ(GetDeviceId(kDeviceDCIM1
), device_info
.device_id());
634 EXPECT_EQ(test_path_a
.value(), device_info
.location());
636 // One device attached at multiple points.
637 // kDeviceDCIM1 -> kMountPointA *
638 // kDeviceFixed -> kMountPointB
639 // kDeviceFixed -> kMountPointC
640 MtabTestData test_data2
[] = {
641 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
642 MtabTestData(kDeviceFixed
, test_path_b
.value(), kValidFS
),
643 MtabTestData(kDeviceFixed
, test_path_c
.value(), kValidFS
),
645 AppendToMtabAndRunLoop(test_data2
, arraysize(test_data2
));
647 EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_a
, &device_info
));
648 EXPECT_EQ(GetDeviceId(kDeviceDCIM1
), device_info
.device_id());
650 EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_b
, &device_info
));
651 EXPECT_EQ(GetDeviceId(kDeviceFixed
), device_info
.device_id());
653 EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_c
, &device_info
));
654 EXPECT_EQ(GetDeviceId(kDeviceFixed
), device_info
.device_id());
656 EXPECT_EQ(2, observer().attach_calls());
657 EXPECT_EQ(1, observer().detach_calls());
660 // http://crbug.com/526252 flaky
661 TEST_F(StorageMonitorLinuxTest
, DISABLED_DevicePartitionSize
) {
662 base::FilePath test_path_a
= CreateMountPointWithDCIMDir(kMountPointA
);
663 base::FilePath test_path_b
= CreateMountPointWithoutDCIMDir(kMountPointB
);
664 ASSERT_FALSE(test_path_a
.empty());
665 ASSERT_FALSE(test_path_b
.empty());
667 MtabTestData test_data1
[] = {
668 MtabTestData(kDeviceDCIM1
, test_path_a
.value(), kValidFS
),
669 MtabTestData(kDeviceNoDCIM
, test_path_b
.value(), kValidFS
),
670 MtabTestData(kDeviceFixed
, kInvalidPath
, kInvalidFS
),
672 AppendToMtabAndRunLoop(test_data1
, arraysize(test_data1
));
673 EXPECT_EQ(2, observer().attach_calls());
674 EXPECT_EQ(0, observer().detach_calls());
676 EXPECT_EQ(GetDevicePartitionSize(kDeviceDCIM1
),
677 GetStorageSize(test_path_a
));
678 EXPECT_EQ(GetDevicePartitionSize(kDeviceNoDCIM
),
679 GetStorageSize(test_path_b
));
680 EXPECT_EQ(GetDevicePartitionSize(kInvalidPath
),
681 GetStorageSize(base::FilePath(kInvalidPath
)));
686 } // namespace storage_monitor