storage_monitor_chromeos_unittest.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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.
  4. #include "components/storage_monitor/storage_monitor_chromeos.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <utility>
  8. #include <vector>
  9. #include "ash/components/disks/disk.h"
  10. #include "ash/components/disks/mock_disk_mount_manager.h"
  11. #include "base/bind.h"
  12. #include "base/files/file_util.h"
  13. #include "base/files/scoped_temp_dir.h"
  14. #include "base/run_loop.h"
  15. #include "base/strings/utf_string_conversions.h"
  16. #include "base/test/task_environment.h"
  17. #include "components/storage_monitor/mock_removable_storage_observer.h"
  18. #include "components/storage_monitor/removable_device_constants.h"
  19. #include "components/storage_monitor/storage_info.h"
  20. #include "components/storage_monitor/test_media_transfer_protocol_manager_chromeos.h"
  21. #include "components/storage_monitor/test_storage_monitor.h"
  22. #include "content/public/test/browser_task_environment.h"
  23. #include "mojo/public/cpp/bindings/pending_remote.h"
  24. #include "testing/gtest/include/gtest/gtest.h"
  25. namespace storage_monitor {
  26. namespace {
  27. using ::ash::disks::Disk;
  28. using ::ash::disks::DiskMountManager;
  29. using testing::_;
  30. const char kDevice1[] = "/dev/d1";
  31. const char kDevice1Name[] = "d1";
  32. const char kDevice2[] = "/dev/disk/d2";
  33. const char kDevice2Name[] = "d2";
  34. const char kEmptyDeviceLabel[] = "";
  35. const char kMountPointA[] = "mnt_a";
  36. const char kMountPointB[] = "mnt_b";
  37. const char kSDCardDeviceName1[] = "8.6 MB Amy_SD";
  38. const char kSDCardDeviceName2[] = "8.6 MB SD Card";
  39. const char kSDCardMountPoint1[] = "media/removable/Amy_SD";
  40. const char kSDCardMountPoint2[] = "media/removable/SD Card";
  41. const char kProductName[] = "Z101";
  42. const char kUniqueId1[] = "FFFF-FFFF";
  43. const char kUniqueId2[] = "FFFF-FF0F";
  44. const char kVendorName[] = "CompanyA";
  45. const char kFileSystemType[] = "exfat";
  46. uint64_t kDevice1SizeInBytes = 113048;
  47. uint64_t kDevice2SizeInBytes = 212312;
  48. uint64_t kSDCardSizeInBytes = 9000000;
  49. std::string GetDCIMDeviceId(const std::string& unique_id) {
  50. return StorageInfo::MakeDeviceId(
  51. StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
  52. kFSUniqueIdPrefix + unique_id);
  53. }
  54. // A test version of StorageMonitorCros that exposes protected methods to tests.
  55. class TestStorageMonitorCros : public StorageMonitorCros {
  56. public:
  57. TestStorageMonitorCros() {}
  58. TestStorageMonitorCros(const TestStorageMonitorCros&) = delete;
  59. TestStorageMonitorCros& operator=(const TestStorageMonitorCros&) = delete;
  60. ~TestStorageMonitorCros() override {}
  61. void Init() override {
  62. mojo::PendingRemote<device::mojom::MtpManager> pending_fake_mtp_manager;
  63. auto* fake_mtp_manager =
  64. TestMediaTransferProtocolManagerChromeOS::GetFakeMtpManager();
  65. fake_mtp_manager->AddReceiver(
  66. pending_fake_mtp_manager.InitWithNewPipeAndPassReceiver());
  67. SetMediaTransferProtocolManagerForTest(std::move(pending_fake_mtp_manager));
  68. StorageMonitorCros::Init();
  69. }
  70. void OnMountEvent(DiskMountManager::MountEvent event,
  71. ash::MountError error_code,
  72. const DiskMountManager::MountPoint& mount_info) override {
  73. StorageMonitorCros::OnMountEvent(event, error_code, mount_info);
  74. }
  75. void OnBootDeviceDiskEvent(DiskMountManager::DiskEvent event,
  76. const Disk& disk) override {
  77. StorageMonitorCros::OnBootDeviceDiskEvent(event, disk);
  78. }
  79. bool GetStorageInfoForPath(const base::FilePath& path,
  80. StorageInfo* device_info) const override {
  81. return StorageMonitorCros::GetStorageInfoForPath(path, device_info);
  82. }
  83. void EjectDevice(const std::string& device_id,
  84. base::OnceCallback<void(EjectStatus)> callback) override {
  85. StorageMonitorCros::EjectDevice(device_id, std::move(callback));
  86. }
  87. };
  88. // Wrapper class to test StorageMonitorCros.
  89. class StorageMonitorCrosTest : public testing::Test {
  90. public:
  91. StorageMonitorCrosTest();
  92. StorageMonitorCrosTest(const StorageMonitorCrosTest&) = delete;
  93. StorageMonitorCrosTest& operator=(const StorageMonitorCrosTest&) = delete;
  94. ~StorageMonitorCrosTest() override;
  95. void EjectNotify(StorageMonitor::EjectStatus status);
  96. protected:
  97. // testing::Test:
  98. void SetUp() override;
  99. void TearDown() override;
  100. void MountDevice(ash::MountError error_code,
  101. const DiskMountManager::MountPoint& mount_info,
  102. const std::string& unique_id,
  103. const std::string& device_label,
  104. const std::string& vendor_name,
  105. const std::string& product_name,
  106. ash::DeviceType device_type,
  107. uint64_t device_size_in_bytes);
  108. void UnmountDevice(ash::MountError error_code,
  109. const DiskMountManager::MountPoint& mount_info);
  110. uint64_t GetDeviceStorageSize(const std::string& device_location);
  111. // Create a directory named |dir| relative to the test directory.
  112. // Set |with_dcim_dir| to true if the created directory will have a "DCIM"
  113. // subdirectory.
  114. // Returns the full path to the created directory on success, or an empty
  115. // path on failure.
  116. base::FilePath CreateMountPoint(const std::string& dir, bool with_dcim_dir);
  117. MockRemovableStorageObserver& observer() {
  118. return *mock_storage_observer_;
  119. }
  120. TestStorageMonitorCros* monitor_;
  121. // Owned by DiskMountManager.
  122. ash::disks::MockDiskMountManager* disk_mount_manager_mock_;
  123. StorageMonitor::EjectStatus status_;
  124. private:
  125. content::BrowserTaskEnvironment task_environment_;
  126. // Temporary directory for created test data.
  127. base::ScopedTempDir scoped_temp_dir_;
  128. // Objects that talks with StorageMonitorCros.
  129. std::unique_ptr<MockRemovableStorageObserver> mock_storage_observer_;
  130. };
  131. StorageMonitorCrosTest::StorageMonitorCrosTest()
  132. : monitor_(NULL),
  133. disk_mount_manager_mock_(NULL),
  134. status_(StorageMonitor::EJECT_FAILURE) {}
  135. StorageMonitorCrosTest::~StorageMonitorCrosTest() {
  136. }
  137. void StorageMonitorCrosTest::SetUp() {
  138. ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
  139. disk_mount_manager_mock_ = new ash::disks::MockDiskMountManager();
  140. DiskMountManager::InitializeForTesting(disk_mount_manager_mock_);
  141. disk_mount_manager_mock_->SetupDefaultReplies();
  142. mock_storage_observer_ = std::make_unique<MockRemovableStorageObserver>();
  143. // Initialize the test subject.
  144. TestStorageMonitor::Destroy();
  145. monitor_ = new TestStorageMonitorCros();
  146. std::unique_ptr<StorageMonitor> pass_monitor(monitor_);
  147. StorageMonitor::SetStorageMonitorForTesting(std::move(pass_monitor));
  148. monitor_->Init();
  149. monitor_->AddObserver(mock_storage_observer_.get());
  150. }
  151. void StorageMonitorCrosTest::TearDown() {
  152. monitor_->RemoveObserver(mock_storage_observer_.get());
  153. monitor_ = NULL;
  154. disk_mount_manager_mock_ = NULL;
  155. DiskMountManager::Shutdown();
  156. task_environment_.RunUntilIdle();
  157. }
  158. void StorageMonitorCrosTest::MountDevice(
  159. ash::MountError error_code,
  160. const DiskMountManager::MountPoint& mount_info,
  161. const std::string& unique_id,
  162. const std::string& device_label,
  163. const std::string& vendor_name,
  164. const std::string& product_name,
  165. ash::DeviceType device_type,
  166. uint64_t device_size_in_bytes) {
  167. if (error_code == ash::MountError::kNone) {
  168. disk_mount_manager_mock_->CreateDiskEntryForMountDevice(
  169. mount_info, unique_id, device_label, vendor_name, product_name,
  170. device_type, device_size_in_bytes, false /* is_parent */,
  171. true /* has_media */, false /* on_boot_device */,
  172. true /* on_removable_device */, kFileSystemType);
  173. }
  174. monitor_->OnMountEvent(DiskMountManager::MOUNTING, error_code, mount_info);
  175. task_environment_.RunUntilIdle();
  176. }
  177. void StorageMonitorCrosTest::UnmountDevice(
  178. ash::MountError error_code,
  179. const DiskMountManager::MountPoint& mount_info) {
  180. monitor_->OnMountEvent(DiskMountManager::UNMOUNTING, error_code, mount_info);
  181. if (error_code == ash::MountError::kNone)
  182. disk_mount_manager_mock_->RemoveDiskEntryForMountDevice(mount_info);
  183. task_environment_.RunUntilIdle();
  184. }
  185. uint64_t StorageMonitorCrosTest::GetDeviceStorageSize(
  186. const std::string& device_location) {
  187. StorageInfo info;
  188. if (!monitor_->GetStorageInfoForPath(base::FilePath(device_location), &info))
  189. return 0;
  190. return info.total_size_in_bytes();
  191. }
  192. base::FilePath StorageMonitorCrosTest::CreateMountPoint(
  193. const std::string& dir, bool with_dcim_dir) {
  194. base::FilePath return_path(scoped_temp_dir_.GetPath());
  195. return_path = return_path.AppendASCII(dir);
  196. base::FilePath path(return_path);
  197. if (with_dcim_dir)
  198. path = path.Append(kDCIMDirectoryName);
  199. if (!base::CreateDirectory(path))
  200. return base::FilePath();
  201. return return_path;
  202. }
  203. void StorageMonitorCrosTest::EjectNotify(StorageMonitor::EjectStatus status) {
  204. status_ = status;
  205. }
  206. // Simple test case where we attach and detach a media device.
  207. TEST_F(StorageMonitorCrosTest, BasicAttachDetach) {
  208. base::FilePath mount_path1 = CreateMountPoint(kMountPointA, true);
  209. ASSERT_FALSE(mount_path1.empty());
  210. DiskMountManager::MountPoint mount_info{kDevice1, mount_path1.value(),
  211. ash::MountType::kDevice};
  212. MountDevice(ash::MountError::kNone,
  213. mount_info,
  214. kUniqueId1,
  215. kDevice1Name,
  216. kVendorName,
  217. kProductName,
  218. ash::DeviceType::kUSB,
  219. kDevice1SizeInBytes);
  220. EXPECT_EQ(1, observer().attach_calls());
  221. EXPECT_EQ(0, observer().detach_calls());
  222. EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
  223. observer().last_attached().device_id());
  224. EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
  225. UnmountDevice(ash::MountError::kNone, mount_info);
  226. EXPECT_EQ(1, observer().attach_calls());
  227. EXPECT_EQ(1, observer().detach_calls());
  228. EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
  229. observer().last_detached().device_id());
  230. base::FilePath mount_path2 = CreateMountPoint(kMountPointB, true);
  231. ASSERT_FALSE(mount_path2.empty());
  232. DiskMountManager::MountPoint mount_info2{kDevice2, mount_path2.value(),
  233. ash::MountType::kDevice};
  234. MountDevice(ash::MountError::kNone,
  235. mount_info2,
  236. kUniqueId2,
  237. kDevice2Name,
  238. kVendorName,
  239. kProductName,
  240. ash::DeviceType::kUSB,
  241. kDevice2SizeInBytes);
  242. EXPECT_EQ(2, observer().attach_calls());
  243. EXPECT_EQ(1, observer().detach_calls());
  244. EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
  245. observer().last_attached().device_id());
  246. EXPECT_EQ(mount_path2.value(), observer().last_attached().location());
  247. UnmountDevice(ash::MountError::kNone, mount_info2);
  248. EXPECT_EQ(2, observer().attach_calls());
  249. EXPECT_EQ(2, observer().detach_calls());
  250. EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
  251. observer().last_detached().device_id());
  252. }
  253. // Removable mass storage devices with no dcim folder are also recognized.
  254. TEST_F(StorageMonitorCrosTest, NoDCIM) {
  255. testing::Sequence mock_sequence;
  256. base::FilePath mount_path = CreateMountPoint(kMountPointA, false);
  257. const std::string kUniqueId = "FFFF-FFFF";
  258. ASSERT_FALSE(mount_path.empty());
  259. DiskMountManager::MountPoint mount_info{kDevice1, mount_path.value(),
  260. ash::MountType::kDevice};
  261. const std::string device_id = StorageInfo::MakeDeviceId(
  262. StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
  263. kFSUniqueIdPrefix + kUniqueId);
  264. MountDevice(ash::MountError::kNone,
  265. mount_info,
  266. kUniqueId,
  267. kDevice1Name,
  268. kVendorName,
  269. kProductName,
  270. ash::DeviceType::kUSB,
  271. kDevice1SizeInBytes);
  272. EXPECT_EQ(1, observer().attach_calls());
  273. EXPECT_EQ(0, observer().detach_calls());
  274. EXPECT_EQ(device_id, observer().last_attached().device_id());
  275. EXPECT_EQ(mount_path.value(), observer().last_attached().location());
  276. }
  277. // Non device mounts and mount errors are ignored.
  278. TEST_F(StorageMonitorCrosTest, Ignore) {
  279. testing::Sequence mock_sequence;
  280. base::FilePath mount_path = CreateMountPoint(kMountPointA, true);
  281. const std::string kUniqueId = "FFFF-FFFF";
  282. ASSERT_FALSE(mount_path.empty());
  283. // Mount error.
  284. DiskMountManager::MountPoint mount_info{kDevice1, mount_path.value(),
  285. ash::MountType::kDevice};
  286. MountDevice(ash::MountError::kUnknown,
  287. mount_info,
  288. kUniqueId,
  289. kDevice1Name,
  290. kVendorName,
  291. kProductName,
  292. ash::DeviceType::kUSB,
  293. kDevice1SizeInBytes);
  294. EXPECT_EQ(0, observer().attach_calls());
  295. EXPECT_EQ(0, observer().detach_calls());
  296. // Not a device
  297. mount_info.mount_type = ash::MountType::kArchive;
  298. MountDevice(ash::MountError::kNone,
  299. mount_info,
  300. kUniqueId,
  301. kDevice1Name,
  302. kVendorName,
  303. kProductName,
  304. ash::DeviceType::kUSB,
  305. kDevice1SizeInBytes);
  306. EXPECT_EQ(0, observer().attach_calls());
  307. EXPECT_EQ(0, observer().detach_calls());
  308. // Unsupported file system.
  309. mount_info.mount_type = ash::MountType::kDevice;
  310. mount_info.mount_condition =
  311. ash::disks::MountCondition::kUnsupportedFilesystem;
  312. MountDevice(ash::MountError::kNone,
  313. mount_info,
  314. kUniqueId,
  315. kDevice1Name,
  316. kVendorName,
  317. kProductName,
  318. ash::DeviceType::kUSB,
  319. kDevice1SizeInBytes);
  320. EXPECT_EQ(0, observer().attach_calls());
  321. EXPECT_EQ(0, observer().detach_calls());
  322. }
  323. TEST_F(StorageMonitorCrosTest, SDCardAttachDetach) {
  324. base::FilePath mount_path1 = CreateMountPoint(kSDCardMountPoint1, true);
  325. ASSERT_FALSE(mount_path1.empty());
  326. DiskMountManager::MountPoint mount_info1{
  327. kSDCardDeviceName1, mount_path1.value(), ash::MountType::kDevice};
  328. MountDevice(ash::MountError::kNone,
  329. mount_info1,
  330. kUniqueId2,
  331. kSDCardDeviceName1,
  332. kVendorName,
  333. kProductName,
  334. ash::DeviceType::kSD,
  335. kSDCardSizeInBytes);
  336. EXPECT_EQ(1, observer().attach_calls());
  337. EXPECT_EQ(0, observer().detach_calls());
  338. EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
  339. observer().last_attached().device_id());
  340. EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
  341. UnmountDevice(ash::MountError::kNone, mount_info1);
  342. EXPECT_EQ(1, observer().attach_calls());
  343. EXPECT_EQ(1, observer().detach_calls());
  344. EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
  345. observer().last_detached().device_id());
  346. base::FilePath mount_path2 = CreateMountPoint(kSDCardMountPoint2, true);
  347. ASSERT_FALSE(mount_path2.empty());
  348. DiskMountManager::MountPoint mount_info2{
  349. kSDCardDeviceName2, mount_path2.value(), ash::MountType::kDevice};
  350. MountDevice(ash::MountError::kNone,
  351. mount_info2,
  352. kUniqueId2,
  353. kSDCardDeviceName2,
  354. kVendorName,
  355. kProductName,
  356. ash::DeviceType::kSD,
  357. kSDCardSizeInBytes);
  358. EXPECT_EQ(2, observer().attach_calls());
  359. EXPECT_EQ(1, observer().detach_calls());
  360. EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
  361. observer().last_attached().device_id());
  362. EXPECT_EQ(mount_path2.value(), observer().last_attached().location());
  363. UnmountDevice(ash::MountError::kNone, mount_info2);
  364. EXPECT_EQ(2, observer().attach_calls());
  365. EXPECT_EQ(2, observer().detach_calls());
  366. EXPECT_EQ(GetDCIMDeviceId(kUniqueId2),
  367. observer().last_detached().device_id());
  368. }
  369. TEST_F(StorageMonitorCrosTest, AttachDeviceWithEmptyLabel) {
  370. base::FilePath mount_path1 = CreateMountPoint(kMountPointA, true);
  371. ASSERT_FALSE(mount_path1.empty());
  372. DiskMountManager::MountPoint mount_info{
  373. kEmptyDeviceLabel, mount_path1.value(), ash::MountType::kDevice};
  374. MountDevice(ash::MountError::kNone,
  375. mount_info,
  376. kUniqueId1,
  377. kEmptyDeviceLabel,
  378. kVendorName,
  379. kProductName,
  380. ash::DeviceType::kUSB,
  381. kDevice1SizeInBytes);
  382. EXPECT_EQ(1, observer().attach_calls());
  383. EXPECT_EQ(0, observer().detach_calls());
  384. EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
  385. observer().last_attached().device_id());
  386. EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
  387. UnmountDevice(ash::MountError::kNone, mount_info);
  388. EXPECT_EQ(1, observer().attach_calls());
  389. EXPECT_EQ(1, observer().detach_calls());
  390. EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
  391. observer().last_detached().device_id());
  392. }
  393. TEST_F(StorageMonitorCrosTest, GetStorageSize) {
  394. base::FilePath mount_path1 = CreateMountPoint(kMountPointA, true);
  395. ASSERT_FALSE(mount_path1.empty());
  396. DiskMountManager::MountPoint mount_info{
  397. kEmptyDeviceLabel, mount_path1.value(), ash::MountType::kDevice};
  398. MountDevice(ash::MountError::kNone,
  399. mount_info,
  400. kUniqueId1,
  401. kEmptyDeviceLabel,
  402. kVendorName,
  403. kProductName,
  404. ash::DeviceType::kUSB,
  405. kDevice1SizeInBytes);
  406. EXPECT_EQ(1, observer().attach_calls());
  407. EXPECT_EQ(0, observer().detach_calls());
  408. EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
  409. observer().last_attached().device_id());
  410. EXPECT_EQ(mount_path1.value(), observer().last_attached().location());
  411. EXPECT_EQ(kDevice1SizeInBytes, GetDeviceStorageSize(mount_path1.value()));
  412. UnmountDevice(ash::MountError::kNone, mount_info);
  413. EXPECT_EQ(1, observer().attach_calls());
  414. EXPECT_EQ(1, observer().detach_calls());
  415. EXPECT_EQ(GetDCIMDeviceId(kUniqueId1),
  416. observer().last_detached().device_id());
  417. }
  418. TEST_F(StorageMonitorCrosTest, EjectTest) {
  419. base::FilePath mount_path1 = CreateMountPoint(kMountPointA, true);
  420. ASSERT_FALSE(mount_path1.empty());
  421. DiskMountManager::MountPoint mount_info{
  422. kEmptyDeviceLabel, mount_path1.value(), ash::MountType::kDevice};
  423. MountDevice(ash::MountError::kNone,
  424. mount_info,
  425. kUniqueId1,
  426. kEmptyDeviceLabel,
  427. kVendorName,
  428. kProductName,
  429. ash::DeviceType::kUSB,
  430. kDevice1SizeInBytes);
  431. EXPECT_EQ(1, observer().attach_calls());
  432. EXPECT_EQ(0, observer().detach_calls());
  433. // testing::Invoke doesn't handle move-only types, so use a lambda instead.
  434. ON_CALL(*disk_mount_manager_mock_, UnmountPath(_, _))
  435. .WillByDefault([](const std::string& location,
  436. DiskMountManager::UnmountPathCallback cb) {
  437. std::move(cb).Run(ash::MountError::kNone);
  438. });
  439. EXPECT_CALL(*disk_mount_manager_mock_,
  440. UnmountPath(observer().last_attached().location(), _));
  441. monitor_->EjectDevice(observer().last_attached().device_id(),
  442. base::BindOnce(&StorageMonitorCrosTest::EjectNotify,
  443. base::Unretained(this)));
  444. base::RunLoop().RunUntilIdle();
  445. EXPECT_EQ(StorageMonitor::EJECT_OK, status_);
  446. }
  447. TEST_F(StorageMonitorCrosTest, FixedStroageTest) {
  448. const std::string uuid = "fixed1-uuid";
  449. const std::string mount_point = "/mnt/stateful_partition";
  450. // Fixed storage (stateful partition) added.
  451. const std::string label = "fixed1";
  452. std::unique_ptr<const Disk> disk = Disk::Builder()
  453. .SetMountPath(mount_point)
  454. .SetDeviceLabel(label)
  455. .SetFileSystemUUID(uuid)
  456. .Build();
  457. monitor_->OnBootDeviceDiskEvent(DiskMountManager::DiskEvent::DISK_ADDED,
  458. *disk);
  459. std::vector<StorageInfo> disks = monitor_->GetAllAvailableStorages();
  460. ASSERT_EQ(1U, disks.size());
  461. EXPECT_EQ(mount_point, disks[0].location());
  462. EXPECT_EQ(base::ASCIIToUTF16(label), disks[0].storage_label());
  463. // Fixed storage (not stateful partition) added - ignore.
  464. std::unique_ptr<const Disk> ignored_disk =
  465. Disk::Builder()
  466. .SetMountPath("usr/share/OEM")
  467. .SetDeviceLabel("fixed2")
  468. .SetFileSystemUUID("fixed2-uuid")
  469. .Build();
  470. monitor_->OnBootDeviceDiskEvent(DiskMountManager::DiskEvent::DISK_ADDED,
  471. *ignored_disk);
  472. disks = monitor_->GetAllAvailableStorages();
  473. ASSERT_EQ(1U, disks.size());
  474. EXPECT_EQ(mount_point, disks[0].location());
  475. EXPECT_EQ(base::ASCIIToUTF16(label), disks[0].storage_label());
  476. // Fixed storage (stateful partition) removed.
  477. monitor_->OnBootDeviceDiskEvent(DiskMountManager::DiskEvent::DISK_REMOVED,
  478. *disk);
  479. disks = monitor_->GetAllAvailableStorages();
  480. EXPECT_EQ(0U, disks.size());
  481. }
  482. } // namespace
  483. } // namespace storage_monitor