123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- // StorageMonitorLinux unit tests.
- #include "components/storage_monitor/storage_monitor_linux.h"
- #include <mntent.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <memory>
- #include <string>
- #include "base/bind.h"
- #include "base/check.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/run_loop.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/task/thread_pool/thread_pool_instance.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "components/storage_monitor/mock_removable_storage_observer.h"
- #include "components/storage_monitor/removable_device_constants.h"
- #include "components/storage_monitor/storage_info.h"
- #include "components/storage_monitor/storage_monitor.h"
- #include "components/storage_monitor/test_storage_monitor.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace storage_monitor {
- namespace {
- const char kValidFS[] = "vfat";
- const char kInvalidFS[] = "invalidfs";
- const char kInvalidPath[] = "invalid path does not exist";
- const char kDeviceDCIM1[] = "d1";
- const char kDeviceDCIM2[] = "d2";
- const char kDeviceDCIM3[] = "d3";
- const char kDeviceNoDCIM[] = "d4";
- const char kDeviceFixed[] = "d5";
- const char kInvalidDevice[] = "invalid_device";
- const char kMountPointA[] = "mnt_a";
- const char kMountPointB[] = "mnt_b";
- const char kMountPointC[] = "mnt_c";
- struct TestDeviceData {
- const char* device_path;
- const char* unique_id;
- StorageInfo::Type type;
- uint64_t partition_size_in_bytes;
- };
- const TestDeviceData kTestDeviceData[] = {
- { kDeviceDCIM1, "UUID:FFF0-000F",
- StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM, 88788 },
- { kDeviceDCIM2, "VendorModelSerial:ComName:Model2010:8989",
- StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
- 8773 },
- { kDeviceDCIM3, "VendorModelSerial:::WEM319X792",
- StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM, 22837 },
- { kDeviceNoDCIM, "UUID:ABCD-1234",
- StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM, 512 },
- { kDeviceFixed, "UUID:743A-2349",
- StorageInfo::FIXED_MASS_STORAGE, 17282 },
- };
- std::unique_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path,
- const base::FilePath& mount_point) {
- bool device_found = false;
- size_t i = 0;
- for (; i < std::size(kTestDeviceData); i++) {
- if (device_path.value() == kTestDeviceData[i].device_path) {
- device_found = true;
- break;
- }
- }
- DCHECK(device_found);
- StorageInfo::Type type = kTestDeviceData[i].type;
- auto storage_info = std::make_unique<StorageInfo>(
- StorageInfo::MakeDeviceId(type, kTestDeviceData[i].unique_id),
- mount_point.value(), u"volume label", u"vendor name", u"model name",
- kTestDeviceData[i].partition_size_in_bytes);
- return storage_info;
- }
- uint64_t GetDevicePartitionSize(const std::string& device) {
- for (const auto& data : kTestDeviceData) {
- if (device == data.device_path)
- return data.partition_size_in_bytes;
- }
- return 0;
- }
- std::string GetDeviceId(const std::string& device) {
- for (const auto& data : kTestDeviceData) {
- if (device == data.device_path)
- return StorageInfo::MakeDeviceId(data.type, data.unique_id);
- }
- if (device == kInvalidDevice) {
- return StorageInfo::MakeDeviceId(StorageInfo::FIXED_MASS_STORAGE,
- kInvalidDevice);
- }
- return std::string();
- }
- class TestStorageMonitorLinux : public StorageMonitorLinux {
- public:
- explicit TestStorageMonitorLinux(const base::FilePath& path)
- : StorageMonitorLinux(path) {
- SetGetDeviceInfoCallbackForTest(base::BindRepeating(&GetDeviceInfo));
- }
- TestStorageMonitorLinux(const TestStorageMonitorLinux&) = delete;
- TestStorageMonitorLinux& operator=(const TestStorageMonitorLinux&) = delete;
- ~TestStorageMonitorLinux() override = default;
- void SetOnMtabUpdateCallback(base::OnceClosure on_mtab_update_callback) {
- EXPECT_FALSE(on_mtab_update_callback_);
- on_mtab_update_callback_ = std::move(on_mtab_update_callback);
- }
- private:
- void UpdateMtab(
- const MtabWatcherLinux::MountPointDeviceMap& new_mtab) override {
- StorageMonitorLinux::UpdateMtab(new_mtab);
- if (on_mtab_update_callback_)
- std::move(on_mtab_update_callback_).Run();
- }
- base::OnceClosure on_mtab_update_callback_;
- };
- class StorageMonitorLinuxTest : public testing::Test {
- public:
- struct MtabTestData {
- MtabTestData(const std::string& mount_device,
- const std::string& mount_point,
- const std::string& mount_type)
- : mount_device(mount_device),
- mount_point(mount_point),
- mount_type(mount_type) {
- }
- const std::string mount_device;
- const std::string mount_point;
- const std::string mount_type;
- };
- StorageMonitorLinuxTest() = default;
- StorageMonitorLinuxTest(const StorageMonitorLinuxTest&) = delete;
- StorageMonitorLinuxTest& operator=(const StorageMonitorLinuxTest&) = delete;
- ~StorageMonitorLinuxTest() override = default;
- protected:
- void SetUp() override {
- // Create and set up a temp dir with files for the test.
- ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
- base::FilePath test_dir =
- scoped_temp_dir_.GetPath().AppendASCII("test_etc");
- ASSERT_TRUE(base::CreateDirectory(test_dir));
- mtab_file_ = test_dir.AppendASCII("test_mtab");
- MtabTestData initial_test_data[] = {
- MtabTestData("dummydevice", "dummydir", kInvalidFS),
- };
- WriteToMtab(initial_test_data, std::size(initial_test_data),
- /*overwrite=*/true);
- monitor_ = std::make_unique<TestStorageMonitorLinux>(mtab_file_);
- mock_storage_observer_ = std::make_unique<MockRemovableStorageObserver>();
- monitor_->AddObserver(mock_storage_observer_.get());
- monitor_->Init();
- task_environment_.RunUntilIdle();
- }
- void TearDown() override {
- task_environment_.RunUntilIdle();
- monitor_->RemoveObserver(mock_storage_observer_.get());
- task_environment_.RunUntilIdle();
- // Linux storage monitor must be destroyed on the UI thread, so do it here.
- monitor_.reset();
- }
- // Append mtab entries from the |data| array of size |data_size| to the mtab
- // file, and run the message loop.
- void AppendToMtabAndRunLoop(const MtabTestData* data, size_t data_size) {
- WriteToMtab(data, data_size, /*overwrite=*/false);
- WaitForMtabUpdate();
- }
- // Overwrite the mtab file with mtab entries from the |data| array of size
- // |data_size|, and run the message loop.
- void OverwriteMtabAndRunLoop(const MtabTestData* data, size_t data_size) {
- WriteToMtab(data, data_size, /*overwrite=*/true);
- WaitForMtabUpdate();
- }
- // Simplied version of OverwriteMtabAndRunLoop() that just deletes all the
- // entries in the mtab file.
- void WriteEmptyMtabAndRunLoop() {
- OverwriteMtabAndRunLoop(/*data=*/nullptr, /*data_size=*/0);
- }
- // Create a directory named |dir| relative to the test directory.
- // It has a DCIM directory, so StorageMonitorLinux recognizes it as a media
- // directory.
- base::FilePath CreateMountPointWithDCIMDir(const std::string& dir) {
- return CreateMountPoint(dir, /*with_dcim_dir=*/true);
- }
- // Create a directory named |dir| relative to the test directory.
- // It does not have a DCIM directory, so StorageMonitorLinux does not
- // recognize it as a media directory.
- base::FilePath CreateMountPointWithoutDCIMDir(const std::string& dir) {
- return CreateMountPoint(dir, /*with_dcim_dir=*/false);
- }
- void RemoveDCIMDirFromMountPoint(const std::string& dir) {
- base::FilePath dcim =
- scoped_temp_dir_.GetPath().AppendASCII(dir).Append(kDCIMDirectoryName);
- base::DeleteFile(dcim);
- }
- MockRemovableStorageObserver& observer() {
- return *mock_storage_observer_;
- }
- StorageMonitor* notifier() {
- return monitor_.get();
- }
- uint64_t GetStorageSize(const base::FilePath& path) {
- StorageInfo info;
- if (!notifier()->GetStorageInfoForPath(path, &info))
- return 0;
- return info.total_size_in_bytes();
- }
- private:
- // Invoked after making an mtab update. Blocks (in an active RunLoop) until
- // the mtab changes are detected by the file watcher and side-effects of
- // UpdateMtab() propagate.
- void WaitForMtabUpdate() {
- base::RunLoop run_loop;
- monitor_->SetOnMtabUpdateCallback(run_loop.QuitClosure());
- // Wait until the UpdateMtab() notification comes in from the system
- // (cannot use RunUntilIdle right away as that would racily return early
- // per being idle until the system notification comes in).
- run_loop.Run();
- // UpdateMtab() causes asynchronous work on internal task runners, flush
- // everything to make sure `mock_storage_observer_` gets to observe the
- // change.
- task_environment_.RunUntilIdle();
- }
- // Create a directory named |dir| relative to the test directory.
- // Set |with_dcim_dir| to true if the created directory will have a "DCIM"
- // subdirectory.
- // Returns the full path to the created directory on success, or an empty
- // path on failure.
- base::FilePath CreateMountPoint(const std::string& dir, bool with_dcim_dir) {
- base::FilePath return_path(scoped_temp_dir_.GetPath());
- return_path = return_path.AppendASCII(dir);
- base::FilePath path(return_path);
- if (with_dcim_dir)
- path = path.Append(kDCIMDirectoryName);
- if (!base::CreateDirectory(path))
- return base::FilePath();
- return return_path;
- }
- // Write the test mtab data to |mtab_file_|.
- // |data| is an array of mtab entries.
- // |data_size| is the array size of |data|.
- // |overwrite| specifies whether to overwrite |mtab_file_|.
- void WriteToMtab(const MtabTestData* data,
- size_t data_size,
- bool overwrite) {
- FILE* file = setmntent(mtab_file_.value().c_str(), overwrite ? "w" : "a");
- ASSERT_TRUE(file);
- // Due to the glibc *mntent() interface design, which is out of our
- // control, the mtnent struct has several char* fields, even though
- // addmntent() does not write to them in the calls below. To make the
- // compiler happy while avoiding making additional copies of strings,
- // we just const_cast() the strings' c_str()s.
- // Assuming addmntent() does not write to the char* fields, this is safe.
- // It is unlikely the platforms this test suite runs on will have an
- // addmntent() implementation that does change the char* fields. If that
- // was ever the case, the test suite will start crashing or failing.
- mntent entry;
- static const char kMountOpts[] = "rw";
- entry.mnt_opts = const_cast<char*>(kMountOpts);
- entry.mnt_freq = 0;
- entry.mnt_passno = 0;
- for (size_t i = 0; i < data_size; ++i) {
- entry.mnt_fsname = const_cast<char*>(data[i].mount_device.c_str());
- entry.mnt_dir = const_cast<char*>(data[i].mount_point.c_str());
- entry.mnt_type = const_cast<char*>(data[i].mount_type.c_str());
- ASSERT_EQ(0, addmntent(file, &entry));
- }
- ASSERT_EQ(1, endmntent(file));
- }
- base::test::TaskEnvironment task_environment_;
- std::unique_ptr<MockRemovableStorageObserver> mock_storage_observer_;
- // Temporary directory for created test data.
- base::ScopedTempDir scoped_temp_dir_;
- // Path to the test mtab file.
- base::FilePath mtab_file_;
- std::unique_ptr<TestStorageMonitorLinux> monitor_;
- };
- // TODO(https://crbug.com/1297464): This test is flaky.
- // Simple test case where we attach and detach a media device.
- TEST_F(StorageMonitorLinuxTest, DISABLED_BasicAttachDetach) {
- base::FilePath test_path = CreateMountPointWithDCIMDir(kMountPointA);
- ASSERT_FALSE(test_path.empty());
- MtabTestData test_data[] = {
- MtabTestData(kDeviceDCIM2, test_path.value(), kValidFS),
- MtabTestData(kDeviceFixed, kInvalidPath, kValidFS),
- };
- // Only |kDeviceDCIM2| should be attached, since |kDeviceFixed| has a bad
- // path.
- AppendToMtabAndRunLoop(test_data, std::size(test_data));
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- EXPECT_EQ(GetDeviceId(kDeviceDCIM2), observer().last_attached().device_id());
- EXPECT_EQ(test_path.value(), observer().last_attached().location());
- // |kDeviceDCIM2| should be detached here.
- WriteEmptyMtabAndRunLoop();
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- EXPECT_EQ(GetDeviceId(kDeviceDCIM2), observer().last_detached().device_id());
- }
- // Only removable devices are recognized.
- // This test is flaky, see https://crbug.com/1012211
- TEST_F(StorageMonitorLinuxTest, Removable) {
- base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
- ASSERT_FALSE(test_path_a.empty());
- MtabTestData test_data1[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- };
- // |kDeviceDCIM1| should be attached as expected.
- AppendToMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- EXPECT_EQ(GetDeviceId(kDeviceDCIM1), observer().last_attached().device_id());
- EXPECT_EQ(test_path_a.value(), observer().last_attached().location());
- // This should do nothing, since |kDeviceFixed| is not removable.
- base::FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB);
- ASSERT_FALSE(test_path_b.empty());
- MtabTestData test_data2[] = {
- MtabTestData(kDeviceFixed, test_path_b.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data2, std::size(test_data2));
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- // |kDeviceDCIM1| should be detached as expected.
- WriteEmptyMtabAndRunLoop();
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- EXPECT_EQ(GetDeviceId(kDeviceDCIM1), observer().last_detached().device_id());
- // |kDeviceNoDCIM| should be attached as expected.
- MtabTestData test_data3[] = {
- MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data3, std::size(test_data3));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- EXPECT_EQ(GetDeviceId(kDeviceNoDCIM), observer().last_attached().device_id());
- EXPECT_EQ(test_path_b.value(), observer().last_attached().location());
- // |kDeviceNoDCIM| should be detached as expected.
- WriteEmptyMtabAndRunLoop();
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(2, observer().detach_calls());
- EXPECT_EQ(GetDeviceId(kDeviceNoDCIM), observer().last_detached().device_id());
- }
- // More complicated test case with multiple devices on multiple mount points.
- TEST_F(StorageMonitorLinuxTest, SwapMountPoints) {
- base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
- base::FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB);
- ASSERT_FALSE(test_path_a.empty());
- ASSERT_FALSE(test_path_b.empty());
- // Attach two devices.
- // (*'d mounts are those StorageMonitor knows about.)
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM2 -> kMountPointB *
- MtabTestData test_data1[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceDCIM2, test_path_b.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- // Detach two devices from old mount points and attach the devices at new
- // mount points.
- // kDeviceDCIM1 -> kMountPointB *
- // kDeviceDCIM2 -> kMountPointA *
- MtabTestData test_data2[] = {
- MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
- MtabTestData(kDeviceDCIM2, test_path_a.value(), kValidFS),
- };
- OverwriteMtabAndRunLoop(test_data2, std::size(test_data2));
- EXPECT_EQ(4, observer().attach_calls());
- EXPECT_EQ(2, observer().detach_calls());
- // Detach all devices.
- WriteEmptyMtabAndRunLoop();
- EXPECT_EQ(4, observer().attach_calls());
- EXPECT_EQ(4, observer().detach_calls());
- }
- // More complicated test case with multiple devices on multiple mount points.
- TEST_F(StorageMonitorLinuxTest, MultiDevicesMultiMountPoints) {
- base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
- base::FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB);
- ASSERT_FALSE(test_path_a.empty());
- ASSERT_FALSE(test_path_b.empty());
- // Attach two devices.
- // (*'d mounts are those StorageMonitor knows about.)
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM2 -> kMountPointB *
- MtabTestData test_data1[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceDCIM2, test_path_b.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- // Attach |kDeviceDCIM1| to |kMountPointB|.
- // |kDeviceDCIM2| is inaccessible, so it is detached. |kDeviceDCIM1| has been
- // attached at |kMountPointB|, but is still accessible from |kMountPointA|.
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM2 -> kMountPointB
- // kDeviceDCIM1 -> kMountPointB
- MtabTestData test_data2[] = {
- MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data2, std::size(test_data2));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- // Detach |kDeviceDCIM1| from |kMountPointA|, causing a detach and attach
- // event.
- // kDeviceDCIM2 -> kMountPointB
- // kDeviceDCIM1 -> kMountPointB *
- MtabTestData test_data3[] = {
- MtabTestData(kDeviceDCIM2, test_path_b.value(), kValidFS),
- MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
- };
- OverwriteMtabAndRunLoop(test_data3, std::size(test_data3));
- EXPECT_EQ(3, observer().attach_calls());
- EXPECT_EQ(2, observer().detach_calls());
- // Attach |kDeviceDCIM1| to |kMountPointA|.
- // kDeviceDCIM2 -> kMountPointB
- // kDeviceDCIM1 -> kMountPointB *
- // kDeviceDCIM1 -> kMountPointA
- MtabTestData test_data4[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data4, std::size(test_data4));
- EXPECT_EQ(3, observer().attach_calls());
- EXPECT_EQ(2, observer().detach_calls());
- // Detach |kDeviceDCIM1| from |kMountPointB|.
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM2 -> kMountPointB *
- OverwriteMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(5, observer().attach_calls());
- EXPECT_EQ(3, observer().detach_calls());
- // Detach all devices.
- WriteEmptyMtabAndRunLoop();
- EXPECT_EQ(5, observer().attach_calls());
- EXPECT_EQ(5, observer().detach_calls());
- }
- TEST_F(StorageMonitorLinuxTest, MultipleMountPointsWithNonDCIMDevices) {
- base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
- base::FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB);
- ASSERT_FALSE(test_path_a.empty());
- ASSERT_FALSE(test_path_b.empty());
- // Attach to one first.
- // (*'d mounts are those StorageMonitor knows about.)
- // kDeviceDCIM1 -> kMountPointA *
- MtabTestData test_data1[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- // Attach |kDeviceDCIM1| to |kMountPointB|.
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM1 -> kMountPointB
- MtabTestData test_data2[] = {
- MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data2, std::size(test_data2));
- EXPECT_EQ(1, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- // Attach |kDeviceFixed| (a non-removable device) to |kMountPointA|.
- // kDeviceDCIM1 -> kMountPointA
- // kDeviceDCIM1 -> kMountPointB *
- // kDeviceFixed -> kMountPointA
- MtabTestData test_data3[] = {
- MtabTestData(kDeviceFixed, test_path_a.value(), kValidFS),
- };
- RemoveDCIMDirFromMountPoint(kMountPointA);
- AppendToMtabAndRunLoop(test_data3, std::size(test_data3));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- // Detach |kDeviceFixed|.
- // kDeviceDCIM1 -> kMountPointA
- // kDeviceDCIM1 -> kMountPointB *
- MtabTestData test_data4[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
- };
- CreateMountPointWithDCIMDir(kMountPointA);
- OverwriteMtabAndRunLoop(test_data4, std::size(test_data4));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- // Attach |kDeviceNoDCIM| (a non-DCIM device) to |kMountPointB|.
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM1 -> kMountPointB
- // kDeviceNoDCIM -> kMountPointB *
- MtabTestData test_data5[] = {
- MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
- };
- base::DeleteFile(test_path_b.Append(kDCIMDirectoryName));
- AppendToMtabAndRunLoop(test_data5, std::size(test_data5));
- EXPECT_EQ(4, observer().attach_calls());
- EXPECT_EQ(2, observer().detach_calls());
- // Detach |kDeviceNoDCIM|.
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceDCIM1 -> kMountPointB
- MtabTestData test_data6[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceDCIM1, test_path_b.value(), kValidFS),
- };
- CreateMountPointWithDCIMDir(kMountPointB);
- OverwriteMtabAndRunLoop(test_data6, std::size(test_data6));
- EXPECT_EQ(4, observer().attach_calls());
- EXPECT_EQ(3, observer().detach_calls());
- // Detach |kDeviceDCIM1| from |kMountPointB|.
- // kDeviceDCIM1 -> kMountPointA *
- OverwriteMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(4, observer().attach_calls());
- EXPECT_EQ(3, observer().detach_calls());
- // Detach all devices.
- WriteEmptyMtabAndRunLoop();
- EXPECT_EQ(4, observer().attach_calls());
- EXPECT_EQ(4, observer().detach_calls());
- }
- TEST_F(StorageMonitorLinuxTest, DeviceLookUp) {
- base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
- base::FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB);
- base::FilePath test_path_c = CreateMountPointWithoutDCIMDir(kMountPointC);
- ASSERT_FALSE(test_path_a.empty());
- ASSERT_FALSE(test_path_b.empty());
- ASSERT_FALSE(test_path_c.empty());
- // Attach to one first.
- // (starred mounts are those StorageMonitor knows about.)
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceNoDCIM -> kMountPointB *
- // kDeviceFixed -> kMountPointC
- MtabTestData test_data1[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
- MtabTestData(kDeviceFixed, test_path_c.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- StorageInfo device_info;
- EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_a, &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceDCIM1), device_info.device_id());
- EXPECT_EQ(test_path_a.value(), device_info.location());
- EXPECT_EQ(88788ULL, device_info.total_size_in_bytes());
- EXPECT_EQ(u"volume label", device_info.storage_label());
- EXPECT_EQ(u"vendor name", device_info.vendor_name());
- EXPECT_EQ(u"model name", device_info.model_name());
- EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_b, &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceNoDCIM), device_info.device_id());
- EXPECT_EQ(test_path_b.value(), device_info.location());
- EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_c, &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceFixed), device_info.device_id());
- EXPECT_EQ(test_path_c.value(), device_info.location());
- // An invalid path.
- EXPECT_FALSE(notifier()->GetStorageInfoForPath(base::FilePath(kInvalidPath),
- &device_info));
- // Test filling in of the mount point.
- EXPECT_TRUE(
- notifier()->GetStorageInfoForPath(test_path_a.Append("some/other/path"),
- &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceDCIM1), device_info.device_id());
- EXPECT_EQ(test_path_a.value(), device_info.location());
- // One device attached at multiple points.
- // kDeviceDCIM1 -> kMountPointA *
- // kDeviceFixed -> kMountPointB
- // kDeviceFixed -> kMountPointC
- MtabTestData test_data2[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceFixed, test_path_b.value(), kValidFS),
- MtabTestData(kDeviceFixed, test_path_c.value(), kValidFS),
- };
- AppendToMtabAndRunLoop(test_data2, std::size(test_data2));
- EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_a, &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceDCIM1), device_info.device_id());
- EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_b, &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceFixed), device_info.device_id());
- EXPECT_TRUE(notifier()->GetStorageInfoForPath(test_path_c, &device_info));
- EXPECT_EQ(GetDeviceId(kDeviceFixed), device_info.device_id());
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(1, observer().detach_calls());
- }
- TEST_F(StorageMonitorLinuxTest, DevicePartitionSize) {
- base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
- base::FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB);
- ASSERT_FALSE(test_path_a.empty());
- ASSERT_FALSE(test_path_b.empty());
- MtabTestData test_data1[] = {
- MtabTestData(kDeviceDCIM1, test_path_a.value(), kValidFS),
- MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
- MtabTestData(kDeviceFixed, kInvalidPath, kInvalidFS),
- };
- AppendToMtabAndRunLoop(test_data1, std::size(test_data1));
- EXPECT_EQ(2, observer().attach_calls());
- EXPECT_EQ(0, observer().detach_calls());
- EXPECT_EQ(GetDevicePartitionSize(kDeviceDCIM1),
- GetStorageSize(test_path_a));
- EXPECT_EQ(GetDevicePartitionSize(kDeviceNoDCIM),
- GetStorageSize(test_path_b));
- EXPECT_EQ(GetDevicePartitionSize(kInvalidPath),
- GetStorageSize(base::FilePath(kInvalidPath)));
- }
- } // namespace
- } // namespace storage_monitor
|