disk_mount_manager_unittest.cc 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751
  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. #include "ash/components/disks/disk_mount_manager.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "ash/components/disks/disk.h"
  12. #include "base/bind.h"
  13. #include "base/run_loop.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "base/test/bind.h"
  16. #include "base/test/mock_callback.h"
  17. #include "base/test/task_environment.h"
  18. #include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
  19. #include "chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.h"
  20. #include "chromeos/dbus/power/power_manager_client.h"
  21. #include "dbus/message.h"
  22. #include "testing/gmock/include/gmock/gmock.h"
  23. #include "testing/gtest/include/gtest/gtest.h"
  24. using base::StringPrintf;
  25. using testing::_;
  26. using testing::Field;
  27. namespace ash {
  28. namespace disks {
  29. namespace {
  30. const char kDevice1SourcePath[] = "/device/source_path";
  31. const char kDevice1MountPath[] = "/device/mount_path";
  32. const char kDevice2SourcePath[] = "/device/source_path2";
  33. const char kReadOnlyDeviceMountPath[] = "/device/read_only_mount_path";
  34. const char kReadOnlyDeviceSourcePath[] = "/device/read_only_source_path";
  35. const char kFileSystemType1[] = "ntfs";
  36. const char kFileSystemType2[] = "exfat";
  37. const FormatFileSystemType kFormatFileSystemType1 = FormatFileSystemType::kVfat;
  38. const FormatFileSystemType kFormatFileSystemType2 =
  39. FormatFileSystemType::kExfat;
  40. const char kFormatFileSystemType1String[] = "vfat";
  41. const char kFormatFileSystemType2String[] = "exfat";
  42. const char kFormatLabel1[] = "UNTITLED";
  43. const char kFormatLabel2[] = "TESTUSB";
  44. // Holds information needed to create a Disk instance.
  45. struct TestDiskInfo {
  46. const char* source_path;
  47. const char* mount_path;
  48. const char* file_path;
  49. const char* device_label;
  50. const char* drive_label;
  51. const char* vendor_id;
  52. const char* vendor_name;
  53. const char* product_id;
  54. const char* product_name;
  55. const char* fs_uuid;
  56. const char* storage_device_path;
  57. DeviceType device_type;
  58. uint64_t size_in_bytes;
  59. bool is_read_only;
  60. const char* file_system_type;
  61. bool is_mounted;
  62. };
  63. // List of disks held in DiskMountManager at the beginning of the test.
  64. const TestDiskInfo kTestDisks[] = {
  65. {
  66. kDevice1SourcePath,
  67. kDevice1MountPath,
  68. "/device/file_path",
  69. "/device/device_label",
  70. "/device/drive_label",
  71. "/device/vendor_id",
  72. "/device/vendor_name",
  73. "/device/product_id",
  74. "/device/product_name",
  75. "/device/fs_uuid",
  76. "/device/prefix",
  77. DeviceType::kUSB,
  78. 1073741824, // size in bytes
  79. false, // is read only
  80. kFileSystemType1,
  81. true, // is_mounted
  82. },
  83. {
  84. kDevice2SourcePath,
  85. "", // not mounted initially
  86. "/device/file_path2",
  87. "/device/device_label2",
  88. "/device/drive_label2",
  89. "/device/vendor_id2",
  90. "/device/vendor_name2",
  91. "/device/product_id2",
  92. "/device/product_name2",
  93. "/device/fs_uuid2",
  94. "/device/prefix2",
  95. DeviceType::kSD,
  96. 1073741824, // size in bytes
  97. false, // is read only
  98. kFileSystemType2,
  99. false, // is_mounted
  100. },
  101. {
  102. kReadOnlyDeviceSourcePath,
  103. kReadOnlyDeviceMountPath,
  104. "/device/file_path_3",
  105. "/device/device_label_3",
  106. "/device/drive_label_3",
  107. "/device/vendor_id_3",
  108. "/device/vendor_name_3",
  109. "/device/product_id_3",
  110. "/device/product_name_3",
  111. "/device/fs_uuid_3",
  112. "/device/prefix",
  113. DeviceType::kUSB,
  114. 1073741824, // size in bytes
  115. true, // is read only
  116. kFileSystemType2,
  117. true, // is_mounted
  118. },
  119. };
  120. // Represents which function in |DiskMountManager::Observer| was invoked.
  121. enum ObserverEventType {
  122. DEVICE_EVENT, // OnDeviceEvent()
  123. AUTO_MOUNTABLE_DISK_EVENT, // OnAutoMountableDiskEvent()
  124. BOOT_DEVICE_DISK_EVENT, // OnBootDeviceDiskEvent()
  125. FORMAT_EVENT, // OnFormatEvent()
  126. MOUNT_EVENT, // OnMountEvent()
  127. RENAME_EVENT // OnRenameEvent()
  128. };
  129. // Represents every event notified to |DiskMountManager::Observer|.
  130. struct ObserverEvent {
  131. public:
  132. virtual ObserverEventType type() const = 0;
  133. virtual ~ObserverEvent() = default;
  134. };
  135. // Represents an invocation of |DiskMountManager::Observer::OnDeviceEvent()|.
  136. struct DeviceEvent : public ObserverEvent {
  137. DiskMountManager::DeviceEvent event;
  138. std::string device_path;
  139. DeviceEvent() = default;
  140. DeviceEvent(DiskMountManager::DeviceEvent event,
  141. const std::string& device_path)
  142. : event(event), device_path(device_path) {}
  143. ObserverEventType type() const override { return DEVICE_EVENT; }
  144. bool operator==(const DeviceEvent& other) const {
  145. return event == other.event && device_path == other.device_path;
  146. }
  147. std::string DebugString() const {
  148. return StringPrintf("OnDeviceEvent(%d, %s)", event, device_path.c_str());
  149. }
  150. };
  151. // Represents an invocation of
  152. // DiskMountManager::Observer::OnAutoMountableDiskEvent().
  153. struct AutoMountableDiskEvent : public ObserverEvent {
  154. DiskMountManager::DiskEvent event;
  155. std::unique_ptr<Disk> disk;
  156. AutoMountableDiskEvent(DiskMountManager::DiskEvent event, const Disk& disk)
  157. : event(event), disk(std::make_unique<Disk>(disk)) {}
  158. AutoMountableDiskEvent(AutoMountableDiskEvent&& other)
  159. : event(other.event), disk(std::move(other.disk)) {}
  160. ObserverEventType type() const override { return AUTO_MOUNTABLE_DISK_EVENT; }
  161. bool operator==(const AutoMountableDiskEvent& other) const {
  162. return event == other.event && disk == other.disk;
  163. }
  164. std::string DebugString() const {
  165. return StringPrintf(
  166. "OnAutoMountableDiskEvent(event=%d, device_path=%s, mount_path=%s",
  167. event, disk->device_path().c_str(), disk->mount_path().c_str());
  168. }
  169. };
  170. // Represents an invocation of
  171. // DiskMountManager::Observer::OnBootDeviceDiskEvent().
  172. // TODO(agawronska): Add tests for disks events.
  173. struct BootDeviceDiskEvent : public ObserverEvent {
  174. DiskMountManager::DiskEvent event;
  175. std::unique_ptr<Disk> disk;
  176. BootDeviceDiskEvent(DiskMountManager::DiskEvent event, const Disk& disk)
  177. : event(event), disk(std::make_unique<Disk>(disk)) {}
  178. BootDeviceDiskEvent(BootDeviceDiskEvent&& other)
  179. : event(other.event), disk(std::move(other.disk)) {}
  180. ObserverEventType type() const override { return BOOT_DEVICE_DISK_EVENT; }
  181. bool operator==(const BootDeviceDiskEvent& other) const {
  182. return event == other.event && disk == other.disk;
  183. }
  184. std::string DebugString() const {
  185. return StringPrintf(
  186. "OnBootDeviceDiskEvent(event=%d, device_path=%s, mount_path=%s", event,
  187. disk->device_path().c_str(), disk->mount_path().c_str());
  188. }
  189. };
  190. // Represents an invocation of |DiskMountManager::Observer::OnFormatEvent()|.
  191. struct FormatEvent : public ObserverEvent {
  192. DiskMountManager::FormatEvent event;
  193. FormatError error_code;
  194. std::string device_path;
  195. std::string device_label;
  196. FormatEvent() = default;
  197. FormatEvent(DiskMountManager::FormatEvent event,
  198. FormatError error_code,
  199. const std::string& device_path,
  200. const std::string& device_label)
  201. : event(event),
  202. error_code(error_code),
  203. device_path(device_path),
  204. device_label(device_label) {}
  205. ObserverEventType type() const override { return FORMAT_EVENT; }
  206. bool operator==(const FormatEvent& other) const {
  207. return event == other.event && error_code == other.error_code &&
  208. device_path == other.device_path &&
  209. device_label == other.device_label;
  210. }
  211. std::string DebugString() const {
  212. return StringPrintf("OnFormatEvent(%d, %d, %s, %s)", event, error_code,
  213. device_path.c_str(), device_label.c_str());
  214. }
  215. };
  216. // Represents an invocation of |DiskMountManager::Observer::OnRenameEvent()|.
  217. struct RenameEvent : public ObserverEvent {
  218. DiskMountManager::RenameEvent event;
  219. RenameError error_code;
  220. std::string device_path;
  221. std::string device_label;
  222. RenameEvent(DiskMountManager::RenameEvent event,
  223. RenameError error_code,
  224. const std::string& device_path,
  225. const std::string& device_label)
  226. : event(event),
  227. error_code(error_code),
  228. device_path(device_path),
  229. device_label(device_label) {}
  230. ObserverEventType type() const override { return RENAME_EVENT; }
  231. bool operator==(const RenameEvent& other) const {
  232. return event == other.event && error_code == other.error_code &&
  233. device_path == other.device_path &&
  234. device_label == other.device_label;
  235. }
  236. std::string DebugString() const {
  237. return StringPrintf("OnRenameEvent(%d, %d, %s, %s)", event, error_code,
  238. device_path.c_str(), device_label.c_str());
  239. }
  240. };
  241. // Represents an invocation of |DiskMountManager::Observer::OnMountEvent()|.
  242. struct MountEvent : public ObserverEvent {
  243. DiskMountManager::MountEvent event;
  244. MountError error_code;
  245. DiskMountManager::MountPoint mount_point;
  246. // Not passed to callback, but read by handlers. So it's captured upon
  247. // callback.
  248. std::unique_ptr<Disk> disk;
  249. MountEvent(MountEvent&& other)
  250. : event(other.event),
  251. error_code(other.error_code),
  252. mount_point(other.mount_point),
  253. disk(std::move(other.disk)) {}
  254. MountEvent(DiskMountManager::MountEvent event,
  255. MountError error_code,
  256. const DiskMountManager::MountPoint& mount_point,
  257. const Disk& disk)
  258. : event(event),
  259. error_code(error_code),
  260. mount_point(mount_point),
  261. disk(std::make_unique<Disk>(disk)) {}
  262. ObserverEventType type() const override { return MOUNT_EVENT; }
  263. bool operator==(const MountEvent& other) const;
  264. std::string DebugString() const {
  265. return StringPrintf("OnMountEvent(%d, %d, %s, %s, %d, %d)", event,
  266. error_code, mount_point.source_path.c_str(),
  267. mount_point.mount_path.c_str(), mount_point.mount_type,
  268. mount_point.mount_condition);
  269. }
  270. };
  271. // A mock |Observer| class which records all invocation of the methods invoked
  272. // from DiskMountManager and all the arguments passed to them.
  273. class MockDiskMountManagerObserver : public DiskMountManager::Observer {
  274. public:
  275. explicit MockDiskMountManagerObserver(const DiskMountManager* manager)
  276. : manager_(manager) {}
  277. ~MockDiskMountManagerObserver() override = default;
  278. // Mock notify methods.
  279. void OnDeviceEvent(DiskMountManager::DeviceEvent event,
  280. const std::string& device_path) override {
  281. events_.push_back(std::make_unique<DeviceEvent>(event, device_path));
  282. }
  283. void OnBootDeviceDiskEvent(DiskMountManager::DiskEvent event,
  284. const Disk& disk) override {
  285. // Take a snapshot (copy) of the Disk object at the time of invocation for
  286. // later verification.
  287. events_.push_back(std::make_unique<BootDeviceDiskEvent>(event, disk));
  288. }
  289. void OnAutoMountableDiskEvent(DiskMountManager::DiskEvent event,
  290. const Disk& disk) override {
  291. // Take a snapshot (copy) of the Disk object at the time of invocation for
  292. // later verification.
  293. events_.push_back(std::make_unique<AutoMountableDiskEvent>(event, disk));
  294. }
  295. void OnFormatEvent(DiskMountManager::FormatEvent event,
  296. FormatError error_code,
  297. const std::string& device_path,
  298. const std::string& device_label) override {
  299. events_.push_back(std::make_unique<FormatEvent>(event, error_code,
  300. device_path, device_label));
  301. }
  302. void OnRenameEvent(DiskMountManager::RenameEvent event,
  303. RenameError error_code,
  304. const std::string& device_path,
  305. const std::string& device_label) override {
  306. events_.push_back(std::make_unique<RenameEvent>(event, error_code,
  307. device_path, device_label));
  308. }
  309. void OnMountEvent(DiskMountManager::MountEvent event,
  310. MountError error_code,
  311. const DiskMountManager::MountPoint& mount_point) override {
  312. // Take a snapshot (copy) of a Disk object at the time of invocation.
  313. // It can be verified later besides the arguments.
  314. events_.push_back(std::make_unique<MountEvent>(
  315. event, error_code, mount_point,
  316. *manager_->disks().find(mount_point.source_path)->get()));
  317. }
  318. // Gets invocation history to be verified by testcases.
  319. // Verifies if the |index|th invocation is OnDeviceEvent() and returns
  320. // details.
  321. const DeviceEvent& GetDeviceEvent(size_t index) {
  322. DCHECK_GT(events_.size(), index);
  323. DCHECK_EQ(DEVICE_EVENT, events_[index]->type());
  324. return static_cast<const DeviceEvent&>(*events_[index]);
  325. }
  326. // Verifies if the |index|th invocation is OnAutoMountableDiskEvent() and
  327. // returns details.
  328. const AutoMountableDiskEvent& GetAutoMountableDiskEvent(size_t index) {
  329. DCHECK_GT(events_.size(), index);
  330. DCHECK_EQ(AUTO_MOUNTABLE_DISK_EVENT, events_[index]->type());
  331. return static_cast<const AutoMountableDiskEvent&>(*events_[index]);
  332. }
  333. // Verifies if the |index|th invocation is OnBootDeviceDiskEvent() and returns
  334. // details.
  335. const BootDeviceDiskEvent& GetBootDeviceDiskEvent(size_t index) {
  336. DCHECK_GT(events_.size(), index);
  337. DCHECK_EQ(BOOT_DEVICE_DISK_EVENT, events_[index]->type());
  338. return static_cast<const BootDeviceDiskEvent&>(*events_[index]);
  339. }
  340. // Verifies if the |index|th invocation is OnFormatEvent() and returns
  341. // details.
  342. const FormatEvent& GetFormatEvent(size_t index) {
  343. DCHECK_GT(events_.size(), index);
  344. DCHECK_EQ(FORMAT_EVENT, events_[index]->type());
  345. return static_cast<const FormatEvent&>(*events_[index]);
  346. }
  347. // Verifies if the |index|th invocation is OnRenameEvent() and returns
  348. // details.
  349. const RenameEvent& GetRenameEvent(size_t index) {
  350. DCHECK_GT(events_.size(), index);
  351. DCHECK_EQ(RENAME_EVENT, events_[index]->type());
  352. return static_cast<const RenameEvent&>(*events_[index]);
  353. }
  354. // Verifies if the |index|th invocation is OnMountEvent() and returns details.
  355. const MountEvent& GetMountEvent(size_t index) {
  356. DCHECK_GT(events_.size(), index);
  357. DCHECK_EQ(MOUNT_EVENT, events_[index]->type());
  358. return static_cast<const MountEvent&>(*events_[index]);
  359. }
  360. // Returns number of callback invocations happened so far.
  361. size_t GetEventCount() { return events_.size(); }
  362. // Counts the number of |MountEvent| recorded so far that matches the given
  363. // condition.
  364. size_t CountMountEvents(DiskMountManager::MountEvent mount_event_type,
  365. MountError error_code,
  366. const std::string& mount_path) {
  367. size_t num_matched = 0;
  368. for (const auto& it : events_) {
  369. if (it->type() != MOUNT_EVENT)
  370. continue;
  371. const MountEvent& mount_event = static_cast<const MountEvent&>(*it);
  372. if (mount_event.event == mount_event_type &&
  373. mount_event.error_code == error_code &&
  374. mount_event.mount_point.mount_path == mount_path)
  375. num_matched++;
  376. }
  377. return num_matched;
  378. }
  379. // Counts the number of |FormatEvent| recorded so far that matches with
  380. // |format_event|.
  381. size_t CountFormatEvents(const FormatEvent& exptected_format_event) {
  382. size_t num_matched = 0;
  383. for (const auto& it : events_) {
  384. if (it->type() != FORMAT_EVENT)
  385. continue;
  386. if (static_cast<const FormatEvent&>(*it) == exptected_format_event)
  387. num_matched++;
  388. }
  389. return num_matched;
  390. }
  391. // Counts the number of |RenameEvent| recorded so far that matches with
  392. // |rename_event|.
  393. size_t CountRenameEvents(const RenameEvent& exptected_rename_event) {
  394. size_t num_matched = 0;
  395. for (const auto& event : events_) {
  396. if (event->type() != RENAME_EVENT)
  397. continue;
  398. if (static_cast<const RenameEvent&>(*event) == exptected_rename_event)
  399. num_matched++;
  400. }
  401. return num_matched;
  402. }
  403. private:
  404. // Pointer to the manager object to which this |Observer| is registered.
  405. const DiskMountManager* manager_;
  406. // Records all invocations.
  407. std::vector<std::unique_ptr<ObserverEvent>> events_;
  408. };
  409. // Shift operators of ostream.
  410. // Needed to print values in case of EXPECT_* failure in gtest.
  411. std::ostream& operator<<(std::ostream& stream,
  412. const FormatEvent& format_event) {
  413. return stream << format_event.DebugString();
  414. }
  415. std::ostream& operator<<(std::ostream& stream,
  416. const RenameEvent& rename_event) {
  417. return stream << rename_event.DebugString();
  418. }
  419. class DiskMountManagerTest : public testing::Test {
  420. public:
  421. DiskMountManagerTest()
  422. : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
  423. ~DiskMountManagerTest() override = default;
  424. // Sets up test disks mount manager.
  425. // Initializes disk mount manager disks and mount points.
  426. // Adds a test observer to the disk mount manager.
  427. void SetUp() override {
  428. CrosDisksClient::InitializeFake();
  429. fake_cros_disks_client_ =
  430. static_cast<FakeCrosDisksClient*>(CrosDisksClient::Get());
  431. PowerManagerClient::InitializeFake();
  432. DiskMountManager::Initialize();
  433. InitDisksAndMountPoints();
  434. observer_ = std::make_unique<MockDiskMountManagerObserver>(
  435. DiskMountManager::GetInstance());
  436. DiskMountManager::GetInstance()->AddObserver(observer_.get());
  437. }
  438. // Shuts down dbus thread manager and disk mount manager used in the test.
  439. void TearDown() override {
  440. DiskMountManager::GetInstance()->RemoveObserver(observer_.get());
  441. DiskMountManager::Shutdown();
  442. PowerManagerClient::Shutdown();
  443. CrosDisksClient::Shutdown();
  444. }
  445. protected:
  446. // Checks if disk mount manager contains a mount point with specified mount
  447. // path.
  448. bool HasMountPoint(const std::string& mount_path) {
  449. return DiskMountManager::GetInstance()->mount_points().count(mount_path) !=
  450. 0;
  451. }
  452. private:
  453. // Adds a new disk to the disk mount manager.
  454. void AddTestDisk(const TestDiskInfo& disk) {
  455. std::unique_ptr<Disk> test_disk =
  456. Disk::Builder()
  457. .SetDevicePath(disk.source_path)
  458. .SetMountPath(disk.mount_path)
  459. .SetFilePath(disk.file_path)
  460. .SetDeviceLabel(disk.device_label)
  461. .SetDriveLabel(disk.drive_label)
  462. .SetVendorId(disk.vendor_id)
  463. .SetVendorName(disk.vendor_name)
  464. .SetProductId(disk.product_id)
  465. .SetProductName(disk.product_name)
  466. .SetFileSystemUUID(disk.fs_uuid)
  467. .SetStorageDevicePath(disk.storage_device_path)
  468. .SetDeviceType(disk.device_type)
  469. .SetSizeInBytes(disk.size_in_bytes)
  470. .SetIsReadOnlyHardware(disk.is_read_only)
  471. .SetHasMedia(true)
  472. .SetOnRemovableDevice(true)
  473. .SetFileSystemType(disk.file_system_type)
  474. .SetIsMounted(disk.is_mounted)
  475. .Build();
  476. EXPECT_TRUE(
  477. DiskMountManager::GetInstance()->AddDiskForTest(std::move(test_disk)));
  478. }
  479. // Adds a new mount point to the disk mount manager.
  480. // If the mount point is a device mount point, disk with its source path
  481. // should already be added to the disk mount manager.
  482. void AddTestMountPoint(const DiskMountManager::MountPoint& mount_point) {
  483. EXPECT_TRUE(
  484. DiskMountManager::GetInstance()->AddMountPointForTest(mount_point));
  485. }
  486. // Adds disks and mount points to disk mount manager.
  487. void InitDisksAndMountPoints() {
  488. // Disks should be added first (when adding device mount points it is
  489. // expected that the corresponding disk is already added).
  490. for (const TestDiskInfo& disk : kTestDisks)
  491. AddTestDisk(disk);
  492. AddTestMountPoint(
  493. {"/archive/source_path", "/archive/mount_path", MountType::kArchive});
  494. AddTestMountPoint(
  495. {kDevice1SourcePath, kDevice1MountPath, MountType::kDevice});
  496. AddTestMountPoint({kReadOnlyDeviceSourcePath, kReadOnlyDeviceMountPath,
  497. MountType::kDevice});
  498. }
  499. protected:
  500. FakeCrosDisksClient* fake_cros_disks_client_;
  501. std::unique_ptr<MockDiskMountManagerObserver> observer_;
  502. private:
  503. base::test::TaskEnvironment task_environment_;
  504. };
  505. // Tests that the observer gets notified on attempt to format non existent mount
  506. // point.
  507. TEST_F(DiskMountManagerTest, Format_NotMounted) {
  508. DiskMountManager::GetInstance()->FormatMountedDevice(
  509. "/mount/non_existent", kFormatFileSystemType1, kFormatLabel1);
  510. ASSERT_EQ(1U, observer_->GetEventCount());
  511. EXPECT_EQ(
  512. FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kUnknown,
  513. "/mount/non_existent", kFormatLabel1),
  514. observer_->GetFormatEvent(0));
  515. }
  516. // Tests that the observer gets notified on attempt to format read-only mount
  517. // point.
  518. TEST_F(DiskMountManagerTest, Format_ReadOnly) {
  519. DiskMountManager::GetInstance()->FormatMountedDevice(
  520. kReadOnlyDeviceMountPath, kFormatFileSystemType1, kFormatLabel1);
  521. ASSERT_EQ(1U, observer_->GetEventCount());
  522. EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
  523. FormatError::kDeviceNotAllowed,
  524. kReadOnlyDeviceSourcePath, kFormatLabel1),
  525. observer_->GetFormatEvent(0));
  526. }
  527. // Tests that it is not possible to format archive mount point.
  528. TEST_F(DiskMountManagerTest, Format_Archive) {
  529. DiskMountManager::GetInstance()->FormatMountedDevice(
  530. "/archive/mount_path", kFormatFileSystemType1, kFormatLabel1);
  531. ASSERT_EQ(1U, observer_->GetEventCount());
  532. EXPECT_EQ(
  533. FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kUnknown,
  534. "/archive/source_path", kFormatLabel1),
  535. observer_->GetFormatEvent(0));
  536. }
  537. // Tests that format fails if the device cannot be unmounted.
  538. TEST_F(DiskMountManagerTest, Format_FailToUnmount) {
  539. // Before formatting mounted device, the device should be unmounted.
  540. // In this test unmount will fail, and there should be no attempt to
  541. // format the device.
  542. fake_cros_disks_client_->MakeUnmountFail(
  543. MountError::kInsufficientPermissions);
  544. // Start test.
  545. DiskMountManager::GetInstance()->FormatMountedDevice(
  546. kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
  547. // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  548. base::RunLoop().RunUntilIdle();
  549. // Observer should be notified that unmount attempt fails and format task
  550. // failed to start.
  551. ASSERT_EQ(2U, observer_->GetEventCount());
  552. const MountEvent& mount_event = observer_->GetMountEvent(0);
  553. EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
  554. EXPECT_EQ(MountError::kInsufficientPermissions, mount_event.error_code);
  555. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  556. EXPECT_EQ(
  557. FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kUnknown,
  558. kDevice1SourcePath, kFormatLabel1),
  559. observer_->GetFormatEvent(1));
  560. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  561. EXPECT_EQ(kDevice1MountPath,
  562. fake_cros_disks_client_->last_unmount_device_path());
  563. EXPECT_EQ(0, fake_cros_disks_client_->format_call_count());
  564. // The device mount should still be here.
  565. EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
  566. }
  567. // Tests that observer is notified when cros disks fails to start format
  568. // process.
  569. TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) {
  570. // Before formatting mounted device, the device should be unmounted.
  571. // In this test, unmount will succeed, but call to Format method will
  572. // fail.
  573. fake_cros_disks_client_->MakeFormatFail();
  574. // Start the test.
  575. DiskMountManager::GetInstance()->FormatMountedDevice(
  576. kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
  577. // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  578. base::RunLoop().RunUntilIdle();
  579. // Observer should be notified that the device was unmounted and format task
  580. // failed to start.
  581. ASSERT_EQ(2U, observer_->GetEventCount());
  582. const MountEvent& mount_event = observer_->GetMountEvent(0);
  583. EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
  584. EXPECT_EQ(MountError::kNone, mount_event.error_code);
  585. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  586. EXPECT_EQ(
  587. FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kUnknown,
  588. kDevice1SourcePath, kFormatLabel1),
  589. observer_->GetFormatEvent(1));
  590. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  591. EXPECT_EQ(kDevice1MountPath,
  592. fake_cros_disks_client_->last_unmount_device_path());
  593. EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  594. EXPECT_EQ(kDevice1SourcePath,
  595. fake_cros_disks_client_->last_format_device_path());
  596. EXPECT_EQ(kFormatFileSystemType1String,
  597. fake_cros_disks_client_->last_format_filesystem());
  598. EXPECT_EQ(kFormatLabel1, fake_cros_disks_client_->last_format_label());
  599. // The device mount should be gone.
  600. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  601. }
  602. // Tests the case where there are two format requests for the same device.
  603. TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) {
  604. // Only the first format request should be processed (the second unmount
  605. // request fails because the device is already unmounted at that point).
  606. // CrosDisksClient will report that the format process for the first request
  607. // is successfully started.
  608. fake_cros_disks_client_->set_unmount_listener(
  609. base::BindRepeating(&FakeCrosDisksClient::MakeUnmountFail,
  610. base::Unretained(fake_cros_disks_client_),
  611. MountError::kInvalidUnmountOptions));
  612. // Start the test.
  613. DiskMountManager::GetInstance()->FormatMountedDevice(
  614. kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
  615. DiskMountManager::GetInstance()->FormatMountedDevice(
  616. kDevice1MountPath, kFormatFileSystemType2, kFormatLabel2);
  617. // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  618. base::RunLoop().RunUntilIdle();
  619. // The observer should get a FORMAT_STARTED event for one format request and a
  620. // FORMAT_COMPLETED with an error code for the other format request. The
  621. // formatting will be started only for the first request.
  622. // There should be only one UNMOUNTING event. The result of the second one
  623. // should not be reported as the mount point will go away after the first
  624. // request.
  625. //
  626. // Note that in this test the format completion signal will not be simulated,
  627. // so the observer should not get FORMAT_COMPLETED signal.
  628. ASSERT_EQ(3U, observer_->GetEventCount());
  629. const MountEvent& mount_event = observer_->GetMountEvent(0);
  630. EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
  631. EXPECT_EQ(MountError::kNone, mount_event.error_code);
  632. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  633. EXPECT_EQ(
  634. FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kUnknown,
  635. kDevice1SourcePath, kFormatLabel2),
  636. observer_->GetFormatEvent(1));
  637. EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED, FormatError::kNone,
  638. kDevice1SourcePath, kFormatLabel1),
  639. observer_->GetFormatEvent(2));
  640. EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  641. EXPECT_EQ(kDevice1MountPath,
  642. fake_cros_disks_client_->last_unmount_device_path());
  643. EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  644. EXPECT_EQ(kDevice1SourcePath,
  645. fake_cros_disks_client_->last_format_device_path());
  646. EXPECT_EQ(kFormatFileSystemType1String,
  647. fake_cros_disks_client_->last_format_filesystem());
  648. EXPECT_EQ(kFormatLabel1, fake_cros_disks_client_->last_format_label());
  649. // The device mount should be gone.
  650. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  651. }
  652. // Verifies a |MountEvent| with the given condition. This function only checks
  653. // the |mount_path| in |MountPointInfo| to make sure to match the event with
  654. // preceding mount invocations.
  655. void VerifyMountEvent(const MountEvent& mount_event,
  656. DiskMountManager::MountEvent mount_event_type,
  657. MountError error_code,
  658. const std::string& mount_path) {
  659. EXPECT_EQ(mount_event_type, mount_event.event);
  660. EXPECT_EQ(error_code, mount_event.error_code);
  661. EXPECT_EQ(mount_path, mount_event.mount_point.mount_path);
  662. }
  663. // Tests the case when the format process actually starts and fails.
  664. TEST_F(DiskMountManagerTest, Format_FormatFails) {
  665. // Both unmount and format device cals are successful in this test.
  666. // Start the test.
  667. DiskMountManager::GetInstance()->FormatMountedDevice(
  668. kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
  669. // Wait for Unmount and Format calls to end.
  670. base::RunLoop().RunUntilIdle();
  671. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  672. EXPECT_EQ(kDevice1MountPath,
  673. fake_cros_disks_client_->last_unmount_device_path());
  674. EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  675. EXPECT_EQ(kDevice1SourcePath,
  676. fake_cros_disks_client_->last_format_device_path());
  677. EXPECT_EQ(kFormatFileSystemType1String,
  678. fake_cros_disks_client_->last_format_filesystem());
  679. EXPECT_EQ(kFormatLabel1, fake_cros_disks_client_->last_format_label());
  680. // The device should be unmounted by now.
  681. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  682. // Send failing FORMAT_COMPLETED signal.
  683. // The failure is marked by ! in fromt of the path (but this should change
  684. // soon).
  685. fake_cros_disks_client_->NotifyFormatCompleted(FormatError::kUnknown,
  686. kDevice1SourcePath);
  687. // The observer should get notified that the device was unmounted and that
  688. // formatting has started.
  689. // After the formatting starts, the test will simulate failing
  690. // FORMAT_COMPLETED signal, so the observer should also be notified the
  691. // formatting has failed (FORMAT_COMPLETED event).
  692. ASSERT_EQ(3U, observer_->GetEventCount());
  693. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
  694. MountError::kNone, kDevice1MountPath);
  695. EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED, FormatError::kNone,
  696. kDevice1SourcePath, kFormatLabel1),
  697. observer_->GetFormatEvent(1));
  698. EXPECT_EQ(
  699. FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kUnknown,
  700. kDevice1SourcePath, kFormatLabel1),
  701. observer_->GetFormatEvent(2));
  702. }
  703. // Tests the case when formatting completes successfully.
  704. TEST_F(DiskMountManagerTest, Format_FormatSuccess) {
  705. DiskMountManager* manager = DiskMountManager::GetInstance();
  706. const DiskMountManager::Disks& disks = manager->disks();
  707. // Set up cros disks client mocks.
  708. // Both unmount and format device cals are successful in this test.
  709. // Start the test.
  710. DiskMountManager::GetInstance()->FormatMountedDevice(
  711. kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
  712. // Wait for Unmount and Format calls to end.
  713. base::RunLoop().RunUntilIdle();
  714. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  715. EXPECT_EQ(kDevice1MountPath,
  716. fake_cros_disks_client_->last_unmount_device_path());
  717. EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  718. EXPECT_EQ(kDevice1SourcePath,
  719. fake_cros_disks_client_->last_format_device_path());
  720. EXPECT_EQ(kFormatFileSystemType1String,
  721. fake_cros_disks_client_->last_format_filesystem());
  722. EXPECT_EQ(kFormatLabel1, fake_cros_disks_client_->last_format_label());
  723. // The device should be unmounted by now.
  724. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  725. // Simulate cros_disks reporting success.
  726. fake_cros_disks_client_->NotifyFormatCompleted(FormatError::kNone,
  727. kDevice1SourcePath);
  728. // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
  729. // events (all of them without an error set).
  730. ASSERT_EQ(3U, observer_->GetEventCount());
  731. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
  732. MountError::kNone, kDevice1MountPath);
  733. EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED, FormatError::kNone,
  734. kDevice1SourcePath, kFormatLabel1),
  735. observer_->GetFormatEvent(1));
  736. EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, FormatError::kNone,
  737. kDevice1SourcePath, kFormatLabel1),
  738. observer_->GetFormatEvent(2));
  739. // Disk should have new values for file system type and device label name
  740. EXPECT_EQ(kFormatFileSystemType1String,
  741. disks.find(kDevice1SourcePath)->get()->file_system_type());
  742. EXPECT_EQ(kFormatLabel1,
  743. disks.find(kDevice1SourcePath)->get()->device_label());
  744. }
  745. // Tests that it's possible to format the device twice in a row (this may not be
  746. // true if the list of pending formats is not properly cleared).
  747. TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) {
  748. // All unmount and format device cals are successful in this test.
  749. // Each of the should be made twice (once for each formatting task).
  750. // Start the test.
  751. DiskMountManager::GetInstance()->FormatMountedDevice(
  752. kDevice1MountPath, kFormatFileSystemType1, kFormatLabel1);
  753. // Wait for Unmount and Format calls to end.
  754. base::RunLoop().RunUntilIdle();
  755. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  756. EXPECT_EQ(kDevice1MountPath,
  757. fake_cros_disks_client_->last_unmount_device_path());
  758. EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  759. EXPECT_EQ(kDevice1SourcePath,
  760. fake_cros_disks_client_->last_format_device_path());
  761. EXPECT_EQ(kFormatFileSystemType1String,
  762. fake_cros_disks_client_->last_format_filesystem());
  763. EXPECT_EQ(kFormatLabel1, fake_cros_disks_client_->last_format_label());
  764. // The device should be unmounted by now.
  765. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  766. // Simulate cros_disks reporting success.
  767. fake_cros_disks_client_->NotifyFormatCompleted(FormatError::kNone,
  768. kDevice1SourcePath);
  769. // Simulate the device remounting.
  770. fake_cros_disks_client_->NotifyMountCompleted(
  771. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  772. kDevice1MountPath);
  773. EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
  774. // Try formatting again.
  775. DiskMountManager::GetInstance()->FormatMountedDevice(
  776. kDevice1MountPath, kFormatFileSystemType2, kFormatLabel2);
  777. // Wait for Unmount and Format calls to end.
  778. base::RunLoop().RunUntilIdle();
  779. EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  780. EXPECT_EQ(kDevice1MountPath,
  781. fake_cros_disks_client_->last_unmount_device_path());
  782. EXPECT_EQ(2, fake_cros_disks_client_->format_call_count());
  783. EXPECT_EQ(kDevice1SourcePath,
  784. fake_cros_disks_client_->last_format_device_path());
  785. EXPECT_EQ(kFormatFileSystemType2String,
  786. fake_cros_disks_client_->last_format_filesystem());
  787. EXPECT_EQ(kFormatLabel2, fake_cros_disks_client_->last_format_label());
  788. // Simulate cros_disks reporting success.
  789. fake_cros_disks_client_->NotifyFormatCompleted(FormatError::kNone,
  790. kDevice1SourcePath);
  791. // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
  792. // events (all of them without an error set) twice (once for each formatting
  793. // task).
  794. // Also, there should be a MOUNTING event when the device remounting is
  795. // simulated.
  796. EXPECT_EQ(7U, observer_->GetEventCount());
  797. EXPECT_EQ(1U, observer_->CountFormatEvents(FormatEvent(
  798. DiskMountManager::FORMAT_COMPLETED, FormatError::kNone,
  799. kDevice1SourcePath, kFormatLabel1)));
  800. EXPECT_EQ(1U, observer_->CountFormatEvents(FormatEvent(
  801. DiskMountManager::FORMAT_COMPLETED, FormatError::kNone,
  802. kDevice1SourcePath, kFormatLabel2)));
  803. EXPECT_EQ(1U, observer_->CountFormatEvents(FormatEvent(
  804. DiskMountManager::FORMAT_STARTED, FormatError::kNone,
  805. kDevice1SourcePath, kFormatLabel1)));
  806. EXPECT_EQ(1U, observer_->CountFormatEvents(FormatEvent(
  807. DiskMountManager::FORMAT_STARTED, FormatError::kNone,
  808. kDevice1SourcePath, kFormatLabel2)));
  809. EXPECT_EQ(2U,
  810. observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
  811. MountError::kNone, kDevice1MountPath));
  812. EXPECT_EQ(1U,
  813. observer_->CountMountEvents(DiskMountManager::MOUNTING,
  814. MountError::kNone, kDevice1MountPath));
  815. }
  816. TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) {
  817. DiskMountManager* manager = DiskMountManager::GetInstance();
  818. const std::string kSourcePath1 = kDevice1SourcePath;
  819. const std::string kSourcePath2 = kDevice2SourcePath;
  820. const std::string kSourceFormat = std::string();
  821. const std::string kMountLabel = std::string(); // N/A for MountType::kDevice
  822. // For MountCompleted. Must be non-empty strings.
  823. const std::string kMountPath1 = "/media/foo";
  824. const std::string kMountPath2 = "/media/bar";
  825. // MountPath should call the given callback when the mount completes.
  826. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback1;
  827. EXPECT_CALL(
  828. mock_callback1,
  829. Run(MountError::kNone,
  830. Field(&DiskMountManager::MountPoint::mount_path, kMountPath1)));
  831. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2;
  832. EXPECT_CALL(
  833. mock_callback2,
  834. Run(MountError::kNone,
  835. Field(&DiskMountManager::MountPoint::mount_path, kMountPath2)))
  836. .WillOnce([&](MountError,
  837. const DiskMountManager::MountPoint& mount_point) {
  838. // Verify the disk appears read-only when the callback is invoked. See
  839. // below comment about the 2nd source.
  840. EXPECT_TRUE(manager->disks()
  841. .find(mount_point.source_path)
  842. ->get()
  843. ->is_read_only());
  844. });
  845. manager->MountPath(kSourcePath1, kSourceFormat, std::string(), {},
  846. MountType::kDevice, MountAccessMode::kReadWrite,
  847. mock_callback1.Get());
  848. manager->MountPath(kSourcePath2, kSourceFormat, std::string(), {},
  849. MountType::kDevice, MountAccessMode::kReadOnly,
  850. mock_callback2.Get());
  851. // Simulate cros_disks reporting mount completed.
  852. fake_cros_disks_client_->NotifyMountCompleted(
  853. MountError::kNone, kSourcePath1, MountType::kDevice, kMountPath1);
  854. fake_cros_disks_client_->NotifyMountCompleted(
  855. MountError::kNone, kSourcePath2, MountType::kDevice, kMountPath2);
  856. // Event handlers of observers should be called.
  857. ASSERT_EQ(2U, observer_->GetEventCount());
  858. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
  859. MountError::kNone, kMountPath1);
  860. // For the 2nd source, the disk (block device) is not read-only but the
  861. // test will mount it in read-only mode.
  862. // Observers query |disks_| from |DiskMountManager| in its event handler for
  863. // a mount completion event. Therefore |disks_| must be updated with correct
  864. // |read_only| value before notifying to observers.
  865. const MountEvent& secondMountEvent = observer_->GetMountEvent(1);
  866. EXPECT_EQ(DiskMountManager::MOUNTING, secondMountEvent.event);
  867. EXPECT_EQ(MountError::kNone, secondMountEvent.error_code);
  868. EXPECT_EQ(kMountPath2, secondMountEvent.mount_point.mount_path);
  869. // Verify if the disk appears read-only at the time of notification to
  870. // observers.
  871. EXPECT_TRUE(secondMountEvent.disk->is_read_only());
  872. // Verify the final state of manager->disks.
  873. const DiskMountManager::Disks& disks = manager->disks();
  874. ASSERT_GT(disks.count(kSourcePath1), 0U);
  875. EXPECT_FALSE(disks.find(kSourcePath1)->get()->is_read_only());
  876. ASSERT_GT(disks.count(kSourcePath2), 0U);
  877. EXPECT_TRUE(disks.find(kSourcePath2)->get()->is_read_only());
  878. }
  879. TEST_F(DiskMountManagerTest, MountPath_ReadOnlyDevice) {
  880. DiskMountManager* manager = DiskMountManager::GetInstance();
  881. const std::string kSourceFormat = std::string();
  882. const std::string kMountLabel = std::string(); // N/A for MountType::kDevice
  883. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback;
  884. EXPECT_CALL(
  885. mock_callback,
  886. Run(MountError::kNone, Field(&DiskMountManager::MountPoint::mount_path,
  887. kReadOnlyDeviceMountPath)));
  888. // Attempt to mount a read-only device in read-write mode.
  889. manager->MountPath(kReadOnlyDeviceSourcePath, kSourceFormat, std::string(),
  890. {}, MountType::kDevice, MountAccessMode::kReadWrite,
  891. mock_callback.Get());
  892. // Simulate cros_disks reporting mount completed.
  893. fake_cros_disks_client_->NotifyMountCompleted(
  894. MountError::kNone, kReadOnlyDeviceSourcePath, MountType::kDevice,
  895. kReadOnlyDeviceMountPath);
  896. // Event handlers of observers should be called.
  897. ASSERT_EQ(1U, observer_->GetEventCount());
  898. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
  899. MountError::kNone, kReadOnlyDeviceMountPath);
  900. const DiskMountManager::Disks& disks = manager->disks();
  901. ASSERT_GT(disks.count(kReadOnlyDeviceSourcePath), 0U);
  902. // The mounted disk should preserve the read-only flag of the block device.
  903. EXPECT_TRUE(disks.find(kReadOnlyDeviceSourcePath)->get()->is_read_only());
  904. }
  905. TEST_F(DiskMountManagerTest, MountPath_DoubleCall) {
  906. DiskMountManager* manager = DiskMountManager::GetInstance();
  907. const std::string kMountPath1 = "/media/foo";
  908. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback1;
  909. manager->MountPath(kDevice1SourcePath, "", "", {}, MountType::kDevice,
  910. MountAccessMode::kReadWrite, mock_callback1.Get());
  911. {
  912. // While the first mount is occurring, queue up a second mount for the same
  913. // source. It should immediately fail.
  914. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2;
  915. EXPECT_CALL(mock_callback2, Run(MountError::kPathAlreadyMounted, _));
  916. manager->MountPath(kDevice1SourcePath, "", "", {}, MountType::kDevice,
  917. MountAccessMode::kReadWrite, mock_callback2.Get());
  918. }
  919. // Verify the first mount can complete as expected.
  920. EXPECT_CALL(
  921. mock_callback1,
  922. Run(MountError::kNone,
  923. Field(&DiskMountManager::MountPoint::mount_path, kMountPath1)));
  924. fake_cros_disks_client_->NotifyMountCompleted(
  925. MountError::kNone, kDevice1SourcePath, MountType::kDevice, kMountPath1);
  926. }
  927. TEST_F(DiskMountManagerTest, MountPath_CallbackCallsMount) {
  928. DiskMountManager* manager = DiskMountManager::GetInstance();
  929. const std::string kMountPath1 = "/media/foo";
  930. const std::string kMountPath2 = "/media/bar";
  931. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback1;
  932. // Try call MountPath() again in the complete callback of a MountPath() call.
  933. EXPECT_CALL(
  934. mock_callback1,
  935. Run(MountError::kNone,
  936. Field(&DiskMountManager::MountPoint::mount_path, kMountPath1)))
  937. .WillOnce([=](MountError error,
  938. const DiskMountManager::MountPoint& mount_info) {
  939. // Try remount the same path and verify it fails.
  940. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2;
  941. EXPECT_CALL(mock_callback2, Run(MountError::kPathAlreadyMounted, _));
  942. manager->MountPath(kDevice1SourcePath, "", "", {}, MountType::kDevice,
  943. MountAccessMode::kReadWrite, mock_callback2.Get());
  944. // Try mount a different path and verify it succeeds.
  945. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback3;
  946. EXPECT_CALL(
  947. mock_callback3,
  948. Run(MountError::kNone,
  949. Field(&DiskMountManager::MountPoint::mount_path, kMountPath2)));
  950. manager->MountPath(kDevice2SourcePath, "", "", {}, MountType::kDevice,
  951. MountAccessMode::kReadWrite, mock_callback3.Get());
  952. fake_cros_disks_client_->NotifyMountCompleted(
  953. MountError::kNone, kDevice2SourcePath, MountType::kDevice,
  954. kMountPath2);
  955. });
  956. manager->MountPath(kDevice1SourcePath, "", "", {}, MountType::kDevice,
  957. MountAccessMode::kReadWrite, mock_callback1.Get());
  958. fake_cros_disks_client_->NotifyMountCompleted(
  959. MountError::kNone, kDevice1SourcePath, MountType::kDevice, kMountPath1);
  960. }
  961. TEST_F(DiskMountManagerTest, RemountRemovableDrives) {
  962. DiskMountManager* manager = DiskMountManager::GetInstance();
  963. // Initially we have 2 mounted devices.
  964. // kDevice1MountPath --- read-write device, mounted in read-write mode.
  965. // kReadOnlyDeviceMountPath --- read-only device, mounted in read-only mode.
  966. manager->RemountAllRemovableDrives(MountAccessMode::kReadOnly);
  967. // Simulate cros_disks reporting mount completed.
  968. fake_cros_disks_client_->NotifyMountCompleted(
  969. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  970. kDevice1MountPath);
  971. // Should remount disks that are not read-only by its hardware device.
  972. ASSERT_EQ(1U, observer_->GetEventCount());
  973. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
  974. MountError::kNone, kDevice1MountPath);
  975. // The disk is remounted in read-only mode.
  976. EXPECT_TRUE(
  977. manager->FindDiskBySourcePath(kDevice1SourcePath)->is_read_only());
  978. // Remounted disk should also appear as read-only to observers.
  979. EXPECT_TRUE(observer_->GetMountEvent(0).disk->is_read_only());
  980. // Remount in read-write mode again.
  981. manager->RemountAllRemovableDrives(MountAccessMode::kReadWrite);
  982. // Simulate cros_disks reporting mount completed.
  983. fake_cros_disks_client_->NotifyMountCompleted(
  984. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  985. kDevice1MountPath);
  986. // Event handlers of observers should be called.
  987. ASSERT_EQ(2U, observer_->GetEventCount());
  988. VerifyMountEvent(observer_->GetMountEvent(1), DiskMountManager::MOUNTING,
  989. MountError::kNone, kDevice1MountPath);
  990. // The read-write device should be remounted in read-write mode.
  991. EXPECT_FALSE(
  992. manager->FindDiskBySourcePath(kDevice1SourcePath)->is_read_only());
  993. // Remounted disk should also appear as writable to observers.
  994. EXPECT_FALSE(observer_->GetMountEvent(1).disk->is_read_only());
  995. }
  996. // Tests that the observer gets notified on attempt to rename non existent mount
  997. // point.
  998. TEST_F(DiskMountManagerTest, Rename_NotMounted) {
  999. DiskMountManager::GetInstance()->RenameMountedDevice("/mount/non_existent",
  1000. "MYUSB");
  1001. ASSERT_EQ(1U, observer_->GetEventCount());
  1002. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1003. RenameError::kUnknown, "/mount/non_existent", "MYUSB"),
  1004. observer_->GetRenameEvent(0));
  1005. }
  1006. // Tests that the observer gets notified on attempt to rename read-only mount
  1007. // point.
  1008. TEST_F(DiskMountManagerTest, Rename_ReadOnly) {
  1009. DiskMountManager::GetInstance()->RenameMountedDevice(kReadOnlyDeviceMountPath,
  1010. "MYUSB");
  1011. ASSERT_EQ(1U, observer_->GetEventCount());
  1012. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1013. RenameError::kDeviceNotAllowed,
  1014. kReadOnlyDeviceSourcePath, "MYUSB"),
  1015. observer_->GetRenameEvent(0));
  1016. }
  1017. // Tests that it is not possible to rename archive mount point.
  1018. TEST_F(DiskMountManagerTest, Rename_Archive) {
  1019. DiskMountManager::GetInstance()->RenameMountedDevice("/archive/mount_path",
  1020. "MYUSB");
  1021. ASSERT_EQ(1U, observer_->GetEventCount());
  1022. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1023. RenameError::kUnknown, "/archive/source_path", "MYUSB"),
  1024. observer_->GetRenameEvent(0));
  1025. }
  1026. // Tests that rename fails if the device cannot be unmounted.
  1027. TEST_F(DiskMountManagerTest, Rename_FailToUnmount) {
  1028. // Before renaming mounted device, the device should be unmounted.
  1029. // In this test unmount will fail, and there should be no attempt to
  1030. // rename the device.
  1031. fake_cros_disks_client_->MakeUnmountFail(MountError::kUnknown);
  1032. // Start test.
  1033. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1034. "MYUSB");
  1035. // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  1036. base::RunLoop().RunUntilIdle();
  1037. // Observer should be notified that unmount attempt fails and rename task
  1038. // failed to start.
  1039. ASSERT_EQ(2U, observer_->GetEventCount());
  1040. const MountEvent& mount_event = observer_->GetMountEvent(0);
  1041. EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
  1042. EXPECT_EQ(MountError::kUnknown, mount_event.error_code);
  1043. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  1044. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1045. RenameError::kUnknown, kDevice1SourcePath, "MYUSB"),
  1046. observer_->GetRenameEvent(1));
  1047. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  1048. EXPECT_EQ(kDevice1MountPath,
  1049. fake_cros_disks_client_->last_unmount_device_path());
  1050. EXPECT_EQ(0, fake_cros_disks_client_->rename_call_count());
  1051. // The device mount should still be here.
  1052. EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
  1053. }
  1054. // Tests that observer is notified when cros disks fails to start rename
  1055. // process.
  1056. TEST_F(DiskMountManagerTest, Rename_RenameFailsToStart) {
  1057. // Before renaming mounted device, the device should be unmounted.
  1058. // In this test, unmount will succeed, but call to Rename method will
  1059. // fail.
  1060. fake_cros_disks_client_->MakeRenameFail();
  1061. // Start the test.
  1062. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1063. "MYUSB");
  1064. // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  1065. base::RunLoop().RunUntilIdle();
  1066. // Observer should be notified that the device was unmounted and rename task
  1067. // failed to start.
  1068. ASSERT_EQ(2U, observer_->GetEventCount());
  1069. const MountEvent& mount_event = observer_->GetMountEvent(0);
  1070. EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
  1071. EXPECT_EQ(MountError::kNone, mount_event.error_code);
  1072. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  1073. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1074. RenameError::kUnknown, kDevice1SourcePath, "MYUSB"),
  1075. observer_->GetRenameEvent(1));
  1076. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  1077. EXPECT_EQ(kDevice1MountPath,
  1078. fake_cros_disks_client_->last_unmount_device_path());
  1079. EXPECT_EQ(1, fake_cros_disks_client_->rename_call_count());
  1080. EXPECT_EQ(kDevice1SourcePath,
  1081. fake_cros_disks_client_->last_rename_device_path());
  1082. EXPECT_EQ("MYUSB", fake_cros_disks_client_->last_rename_volume_name());
  1083. // The device mount should be gone.
  1084. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  1085. }
  1086. // Tests the case where there are two rename requests for the same device.
  1087. TEST_F(DiskMountManagerTest, Rename_ConcurrentRenameCalls) {
  1088. // Only the first rename request should be processed (the second unmount
  1089. // request fails because the device is already unmounted at that point).
  1090. // CrosDisksClient will report that the rename process for the first request
  1091. // is successfully started.
  1092. fake_cros_disks_client_->set_unmount_listener(base::BindRepeating(
  1093. &FakeCrosDisksClient::MakeUnmountFail,
  1094. base::Unretained(fake_cros_disks_client_), MountError::kInternal));
  1095. // Start the test.
  1096. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1097. "MYUSB1");
  1098. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1099. "MYUSB2");
  1100. // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  1101. base::RunLoop().RunUntilIdle();
  1102. // The observer should get a RENAME_STARTED event for one rename request and a
  1103. // RENAME_COMPLETED with an error code for the other rename request. The
  1104. // renaming will be started only for the first request.
  1105. // There should be only one UNMOUNTING event. The result of the second one
  1106. // should not be reported as the mount point will go away after the first
  1107. // request.
  1108. //
  1109. // Note that in this test the rename completion signal will not be simulated,
  1110. // so the observer should not get RENAME_COMPLETED signal.
  1111. ASSERT_EQ(3U, observer_->GetEventCount());
  1112. const MountEvent& mount_event = observer_->GetMountEvent(0);
  1113. EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
  1114. EXPECT_EQ(MountError::kNone, mount_event.error_code);
  1115. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  1116. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1117. RenameError::kUnknown, kDevice1SourcePath, "MYUSB2"),
  1118. observer_->GetRenameEvent(1));
  1119. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_STARTED, RenameError::kNone,
  1120. kDevice1SourcePath, "MYUSB1"),
  1121. observer_->GetRenameEvent(2));
  1122. EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  1123. EXPECT_EQ(kDevice1MountPath,
  1124. fake_cros_disks_client_->last_unmount_device_path());
  1125. EXPECT_EQ(1, fake_cros_disks_client_->rename_call_count());
  1126. EXPECT_EQ(kDevice1SourcePath,
  1127. fake_cros_disks_client_->last_rename_device_path());
  1128. EXPECT_EQ("MYUSB1", fake_cros_disks_client_->last_rename_volume_name());
  1129. // The device mount should be gone.
  1130. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  1131. }
  1132. // Tests the case when the rename process actually starts and fails.
  1133. TEST_F(DiskMountManagerTest, Rename_RenameFails) {
  1134. // Both unmount and rename device calls are successful in this test.
  1135. // Start the test.
  1136. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1137. "MYUSB");
  1138. // Wait for Unmount and Rename calls to end.
  1139. base::RunLoop().RunUntilIdle();
  1140. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  1141. EXPECT_EQ(kDevice1MountPath,
  1142. fake_cros_disks_client_->last_unmount_device_path());
  1143. EXPECT_EQ(1, fake_cros_disks_client_->rename_call_count());
  1144. EXPECT_EQ(kDevice1SourcePath,
  1145. fake_cros_disks_client_->last_rename_device_path());
  1146. EXPECT_EQ("MYUSB", fake_cros_disks_client_->last_rename_volume_name());
  1147. // The device should be unmounted by now.
  1148. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  1149. // Send failing RENAME_COMPLETED signal.
  1150. // The failure is marked by ! in fromt of the path (but this should change
  1151. // soon).
  1152. fake_cros_disks_client_->NotifyRenameCompleted(RenameError::kUnknown,
  1153. kDevice1SourcePath);
  1154. // The observer should get notified that the device was unmounted and that
  1155. // renaming has started.
  1156. // After the renaming starts, the test will simulate failing
  1157. // RENAME_COMPLETED signal, so the observer should also be notified the
  1158. // renaming has failed (RENAME_COMPLETED event).
  1159. ASSERT_EQ(3U, observer_->GetEventCount());
  1160. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
  1161. MountError::kNone, kDevice1MountPath);
  1162. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_STARTED, RenameError::kNone,
  1163. kDevice1SourcePath, "MYUSB"),
  1164. observer_->GetRenameEvent(1));
  1165. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED,
  1166. RenameError::kUnknown, kDevice1SourcePath, "MYUSB"),
  1167. observer_->GetRenameEvent(2));
  1168. }
  1169. // Tests the case when renaming completes successfully.
  1170. TEST_F(DiskMountManagerTest, Rename_RenameSuccess) {
  1171. DiskMountManager* manager = DiskMountManager::GetInstance();
  1172. const DiskMountManager::Disks& disks = manager->disks();
  1173. // Set up cros disks client mocks.
  1174. // Both unmount and rename device calls are successful in this test.
  1175. // Start the test.
  1176. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1177. "MYUSB1");
  1178. // Wait for Unmount and Rename calls to end.
  1179. base::RunLoop().RunUntilIdle();
  1180. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  1181. EXPECT_EQ(kDevice1MountPath,
  1182. fake_cros_disks_client_->last_unmount_device_path());
  1183. EXPECT_EQ(1, fake_cros_disks_client_->rename_call_count());
  1184. EXPECT_EQ(kDevice1SourcePath,
  1185. fake_cros_disks_client_->last_rename_device_path());
  1186. EXPECT_EQ("MYUSB1", fake_cros_disks_client_->last_rename_volume_name());
  1187. // The device should be unmounted by now.
  1188. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  1189. // Simulate cros_disks reporting success.
  1190. fake_cros_disks_client_->NotifyRenameCompleted(RenameError::kNone,
  1191. kDevice1SourcePath);
  1192. // The observer should receive UNMOUNTING, RENAME_STARTED and RENAME_COMPLETED
  1193. // events (all of them without an error set).
  1194. ASSERT_EQ(3U, observer_->GetEventCount());
  1195. VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
  1196. MountError::kNone, kDevice1MountPath);
  1197. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_STARTED, RenameError::kNone,
  1198. kDevice1SourcePath, "MYUSB1"),
  1199. observer_->GetRenameEvent(1));
  1200. EXPECT_EQ(RenameEvent(DiskMountManager::RENAME_COMPLETED, RenameError::kNone,
  1201. kDevice1SourcePath, "MYUSB1"),
  1202. observer_->GetRenameEvent(2));
  1203. // Disk should have new value for device label name
  1204. EXPECT_EQ("MYUSB1", disks.find(kDevice1SourcePath)->get()->device_label());
  1205. }
  1206. // Tests that it's possible to rename the device twice in a row (this may not be
  1207. // true if the list of pending renames is not properly cleared).
  1208. TEST_F(DiskMountManagerTest, Rename_ConsecutiveRenameCalls) {
  1209. DiskMountManager* manager = DiskMountManager::GetInstance();
  1210. const DiskMountManager::Disks& disks = manager->disks();
  1211. // All unmount and rename device calls are successful in this test.
  1212. // Each of the should be made twice (once for each renaming task).
  1213. // Start the test.
  1214. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1215. "MYUSB");
  1216. // Wait for Unmount and Rename calls to end.
  1217. base::RunLoop().RunUntilIdle();
  1218. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  1219. EXPECT_EQ(kDevice1MountPath,
  1220. fake_cros_disks_client_->last_unmount_device_path());
  1221. EXPECT_EQ(1, fake_cros_disks_client_->rename_call_count());
  1222. EXPECT_EQ(kDevice1SourcePath,
  1223. fake_cros_disks_client_->last_rename_device_path());
  1224. EXPECT_EQ("MYUSB", fake_cros_disks_client_->last_rename_volume_name());
  1225. EXPECT_EQ("", disks.find(kDevice1SourcePath)->get()->base_mount_path());
  1226. // The device should be unmounted by now.
  1227. EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
  1228. // Simulate cros_disks reporting success.
  1229. fake_cros_disks_client_->NotifyRenameCompleted(RenameError::kNone,
  1230. kDevice1SourcePath);
  1231. // Simulate the device remounting.
  1232. fake_cros_disks_client_->NotifyMountCompleted(
  1233. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  1234. kDevice1MountPath);
  1235. EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
  1236. auto previousMountPath = disks.find(kDevice1SourcePath)->get()->mount_path();
  1237. // Try renaming again.
  1238. DiskMountManager::GetInstance()->RenameMountedDevice(kDevice1MountPath,
  1239. "MYUSB2");
  1240. // Wait for Unmount and Rename calls to end.
  1241. base::RunLoop().RunUntilIdle();
  1242. EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  1243. EXPECT_EQ(kDevice1MountPath,
  1244. fake_cros_disks_client_->last_unmount_device_path());
  1245. EXPECT_EQ(2, fake_cros_disks_client_->rename_call_count());
  1246. EXPECT_EQ(kDevice1SourcePath,
  1247. fake_cros_disks_client_->last_rename_device_path());
  1248. EXPECT_EQ("MYUSB2", fake_cros_disks_client_->last_rename_volume_name());
  1249. // Base mount path should be set to previous mount path.
  1250. EXPECT_EQ(previousMountPath,
  1251. disks.find(kDevice1SourcePath)->get()->base_mount_path());
  1252. // Simulate cros_disks reporting success.
  1253. fake_cros_disks_client_->NotifyRenameCompleted(RenameError::kNone,
  1254. kDevice1SourcePath);
  1255. // The observer should receive UNMOUNTING, RENAME_STARTED and RENAME_COMPLETED
  1256. // events (all of them without an error set) twice (once for each renaming
  1257. // task).
  1258. // Also, there should be a MOUNTING event when the device remounting is
  1259. // simulated.
  1260. EXPECT_EQ(7U, observer_->GetEventCount());
  1261. EXPECT_EQ(1U, observer_->CountRenameEvents(RenameEvent(
  1262. DiskMountManager::RENAME_COMPLETED, RenameError::kNone,
  1263. kDevice1SourcePath, "MYUSB2")));
  1264. EXPECT_EQ(1U, observer_->CountRenameEvents(RenameEvent(
  1265. DiskMountManager::RENAME_COMPLETED, RenameError::kNone,
  1266. kDevice1SourcePath, "MYUSB")));
  1267. EXPECT_EQ(1U, observer_->CountRenameEvents(RenameEvent(
  1268. DiskMountManager::RENAME_STARTED, RenameError::kNone,
  1269. kDevice1SourcePath, "MYUSB")));
  1270. EXPECT_EQ(1U, observer_->CountRenameEvents(RenameEvent(
  1271. DiskMountManager::RENAME_STARTED, RenameError::kNone,
  1272. kDevice1SourcePath, "MYUSB2")));
  1273. EXPECT_EQ(2U,
  1274. observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
  1275. MountError::kNone, kDevice1MountPath));
  1276. EXPECT_EQ(1U,
  1277. observer_->CountMountEvents(DiskMountManager::MOUNTING,
  1278. MountError::kNone, kDevice1MountPath));
  1279. }
  1280. void SaveUnmountResult(MountError* save_error,
  1281. base::OnceClosure done_callback,
  1282. MountError error_code) {
  1283. *save_error = error_code;
  1284. std::move(done_callback).Run();
  1285. }
  1286. TEST_F(DiskMountManagerTest, UnmountDeviceRecursively) {
  1287. base::RunLoop run_loop;
  1288. auto disk_sda =
  1289. Disk::Builder().SetDevicePath("/dev/sda").SetIsParent(true).Build();
  1290. EXPECT_TRUE(
  1291. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda)));
  1292. auto disk_sda1 = Disk::Builder()
  1293. .SetDevicePath("/dev/sda1")
  1294. .SetMountPath("/mount/path1")
  1295. .Build();
  1296. EXPECT_TRUE(
  1297. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
  1298. auto disk_sda2 = Disk::Builder()
  1299. .SetDevicePath("/dev/sda2")
  1300. .SetMountPath("/mount/path2")
  1301. .Build();
  1302. EXPECT_TRUE(
  1303. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda2)));
  1304. MountError error_code = MountError::kUnknown;
  1305. DiskMountManager::GetInstance()->UnmountDeviceRecursively(
  1306. "/dev/sda",
  1307. base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
  1308. run_loop.QuitClosure()));
  1309. run_loop.Run();
  1310. EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  1311. EXPECT_EQ(MountError::kNone, error_code);
  1312. }
  1313. TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_NoMounted) {
  1314. base::RunLoop run_loop;
  1315. auto disk_sda =
  1316. Disk::Builder().SetDevicePath("/dev/sda").SetIsParent(true).Build();
  1317. EXPECT_TRUE(
  1318. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda)));
  1319. auto disk_sda1 = Disk::Builder().SetDevicePath("/dev/sda1").Build();
  1320. EXPECT_TRUE(
  1321. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
  1322. MountError error_code = MountError::kUnknown;
  1323. DiskMountManager::GetInstance()->UnmountDeviceRecursively(
  1324. "/dev/sda",
  1325. base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
  1326. run_loop.QuitClosure()));
  1327. run_loop.Run();
  1328. EXPECT_EQ(0, fake_cros_disks_client_->unmount_call_count());
  1329. EXPECT_EQ(MountError::kNone, error_code);
  1330. }
  1331. TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_NoDisk) {
  1332. base::RunLoop run_loop;
  1333. auto disk_sda =
  1334. Disk::Builder().SetDevicePath("/dev/sda").SetIsParent(true).Build();
  1335. EXPECT_TRUE(
  1336. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda)));
  1337. auto disk_sda1 = Disk::Builder().SetDevicePath("/dev/sda1").Build();
  1338. EXPECT_TRUE(
  1339. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
  1340. MountError error_code = MountError::kUnknown;
  1341. // Unmount sdB instead of sdA.
  1342. DiskMountManager::GetInstance()->UnmountDeviceRecursively(
  1343. "/dev/sdb",
  1344. base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
  1345. run_loop.QuitClosure()));
  1346. run_loop.Run();
  1347. EXPECT_EQ(0, fake_cros_disks_client_->unmount_call_count());
  1348. EXPECT_EQ(MountError::kInvalidDevicePath, error_code);
  1349. }
  1350. void SetUnmountError(FakeCrosDisksClient* client, MountError error_code) {
  1351. client->MakeUnmountFail(error_code);
  1352. }
  1353. TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_FailFirst) {
  1354. base::RunLoop run_loop;
  1355. auto disk_sda =
  1356. Disk::Builder().SetDevicePath("/dev/sda").SetIsParent(true).Build();
  1357. EXPECT_TRUE(
  1358. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda)));
  1359. auto disk_sda1 = Disk::Builder()
  1360. .SetDevicePath("/dev/sda1")
  1361. .SetMountPath("/mount/path1")
  1362. .Build();
  1363. EXPECT_TRUE(
  1364. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
  1365. auto disk_sda2 = Disk::Builder()
  1366. .SetDevicePath("/dev/sda2")
  1367. .SetMountPath("/mount/path2")
  1368. .Build();
  1369. EXPECT_TRUE(
  1370. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda2)));
  1371. // Fail the first unmount, but make the second succeed.
  1372. fake_cros_disks_client_->MakeUnmountFail(MountError::kInvalidUnmountOptions);
  1373. fake_cros_disks_client_->set_unmount_listener(base::BindRepeating(
  1374. &SetUnmountError, base::Unretained(fake_cros_disks_client_),
  1375. MountError::kNone));
  1376. MountError error_code = MountError::kUnknown;
  1377. DiskMountManager::GetInstance()->UnmountDeviceRecursively(
  1378. "/dev/sda",
  1379. base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
  1380. run_loop.QuitClosure()));
  1381. run_loop.Run();
  1382. EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  1383. EXPECT_EQ(MountError::kInvalidUnmountOptions, error_code);
  1384. }
  1385. TEST_F(DiskMountManagerTest, UnmountDeviceRecursively_AlreadyUnmounted) {
  1386. base::RunLoop run_loop;
  1387. auto disk_sda =
  1388. Disk::Builder().SetDevicePath("/dev/sda").SetIsParent(true).Build();
  1389. EXPECT_TRUE(
  1390. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda)));
  1391. auto disk_sda1 = Disk::Builder()
  1392. .SetDevicePath("/dev/sda1")
  1393. .SetMountPath("/mount/path1")
  1394. .Build();
  1395. EXPECT_TRUE(
  1396. DiskMountManager::GetInstance()->AddDiskForTest(std::move(disk_sda1)));
  1397. // Fail the unmount with "not mounted".
  1398. fake_cros_disks_client_->MakeUnmountFail(MountError::kPathNotMounted);
  1399. MountError error_code = MountError::kUnknown;
  1400. DiskMountManager::GetInstance()->UnmountDeviceRecursively(
  1401. "/dev/sda",
  1402. base::BindOnce(&SaveUnmountResult, base::Unretained(&error_code),
  1403. run_loop.QuitClosure()));
  1404. run_loop.Run();
  1405. EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  1406. EXPECT_EQ(MountError::kNone, error_code);
  1407. }
  1408. TEST_F(DiskMountManagerTest, Mount_MountUnsetsFirstMount) {
  1409. DiskMountManager* manager = DiskMountManager::GetInstance();
  1410. const Disk* device1 = manager->FindDiskBySourcePath(kDevice1SourcePath);
  1411. EXPECT_TRUE(device1->is_first_mount());
  1412. fake_cros_disks_client_->NotifyMountCompleted(
  1413. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  1414. kDevice1MountPath);
  1415. EXPECT_FALSE(device1->is_first_mount());
  1416. }
  1417. TEST_F(DiskMountManagerTest, Mount_RemountPreservesFirstMount) {
  1418. DiskMountManager* manager = DiskMountManager::GetInstance();
  1419. EXPECT_TRUE(
  1420. manager->FindDiskBySourcePath(kDevice1SourcePath)->is_first_mount());
  1421. std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty();
  1422. DiskInfo disk_info(kDevice1SourcePath, response.get());
  1423. fake_cros_disks_client_->set_next_get_device_properties_disk_info(&disk_info);
  1424. fake_cros_disks_client_->NotifyMountEvent(MountEventType::kDiskAdded,
  1425. kDevice1SourcePath);
  1426. // NotifyMountEvent indirectly invokes CrosDisksClient::GetDeviceProperties,
  1427. // which responds asynchronously.
  1428. base::RunLoop().RunUntilIdle();
  1429. EXPECT_EQ(1, fake_cros_disks_client_->get_device_properties_success_count());
  1430. EXPECT_TRUE(
  1431. manager->FindDiskBySourcePath(kDevice1SourcePath)->is_first_mount());
  1432. fake_cros_disks_client_->NotifyMountCompleted(
  1433. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  1434. kDevice1MountPath);
  1435. EXPECT_FALSE(
  1436. manager->FindDiskBySourcePath(kDevice1SourcePath)->is_first_mount());
  1437. fake_cros_disks_client_->NotifyMountEvent(MountEventType::kDiskAdded,
  1438. kDevice1SourcePath);
  1439. // NotifyMountEvent indirectly invokes CrosDisksClient::GetDeviceProperties,
  1440. // which responds asynchronously.
  1441. base::RunLoop().RunUntilIdle();
  1442. EXPECT_EQ(2, fake_cros_disks_client_->get_device_properties_success_count());
  1443. EXPECT_FALSE(
  1444. manager->FindDiskBySourcePath(kDevice1SourcePath)->is_first_mount());
  1445. }
  1446. TEST_F(DiskMountManagerTest, Mount_DefersDuringGetDeviceProperties) {
  1447. DiskMountManager* manager = DiskMountManager::GetInstance();
  1448. // When a disk is added, we call GetDeviceProperties() before updating our
  1449. // DiskMap. If the disk is mounted before this asynchronous call returns, we
  1450. // defer sending the mount event so that clients are able to access the disk
  1451. // information immediately.
  1452. fake_cros_disks_client_->NotifyMountEvent(MountEventType::kDiskRemoved,
  1453. kDevice1SourcePath);
  1454. EXPECT_EQ(nullptr, manager->FindDiskBySourcePath(kDevice1SourcePath));
  1455. std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty();
  1456. DiskInfo disk_info(kDevice1SourcePath, response.get());
  1457. fake_cros_disks_client_->set_next_get_device_properties_disk_info(&disk_info);
  1458. fake_cros_disks_client_->NotifyMountEvent(MountEventType::kDiskAdded,
  1459. kDevice1SourcePath);
  1460. fake_cros_disks_client_->NotifyMountCompleted(
  1461. MountError::kNone, kDevice1SourcePath, MountType::kDevice,
  1462. kDevice1MountPath);
  1463. // The mount event will not have fired yet as we are still waiting for
  1464. // GetDeviceProperties() to return.
  1465. EXPECT_EQ(0u,
  1466. observer_->CountMountEvents(DiskMountManager::MOUNTING,
  1467. MountError::kNone, kDevice1MountPath));
  1468. base::RunLoop().RunUntilIdle();
  1469. // We have fired 3 events: disk removed -> disk added -> mounting
  1470. const MountEvent& mount_event = observer_->GetMountEvent(2);
  1471. EXPECT_EQ(DiskMountManager::MOUNTING, mount_event.event);
  1472. EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
  1473. // The test OnMountEvent() finds the matching disk when it is called.
  1474. EXPECT_NE(nullptr, mount_event.disk);
  1475. }
  1476. } // namespace
  1477. } // namespace disks
  1478. } // namespace ash