blob: 6d1cc5d549f74b65567ac56cf4cc698504d4c68b [file] [log] [blame]
[email protected]e3c1fc92012-11-15 00:56:461// 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
avi6e1a22d2015-12-21 03:43:205#include <stddef.h>
6#include <stdint.h>
7
[email protected]e3c1fc92012-11-15 00:56:468#include "base/bind.h"
yamaguchicafadf52016-09-15 09:05:539#include "base/memory/ptr_util.h"
[email protected]f129d2502013-07-17 22:45:5010#include "base/message_loop/message_loop.h"
fdorayf5b47fd12016-09-13 14:12:3611#include "base/run_loop.h"
yamaguchicafadf52016-09-15 09:05:5312#include "base/strings/stringprintf.h"
zelidrag29fe3382014-08-27 01:44:4813#include "chromeos/dbus/dbus_thread_manager.h"
[email protected]cc70f5012013-05-14 04:58:5614#include "chromeos/dbus/fake_cros_disks_client.h"
[email protected]e3c1fc92012-11-15 00:56:4615#include "chromeos/disks/disk_mount_manager.h"
[email protected]e3c1fc92012-11-15 00:56:4616#include "testing/gtest/include/gtest/gtest.h"
17
yamaguchicafadf52016-09-15 09:05:5318using base::MakeUnique;
19using base::StringPrintf;
[email protected]e3c1fc92012-11-15 00:56:4620using chromeos::disks::DiskMountManager;
21using chromeos::CrosDisksClient;
22using chromeos::DBusThreadManager;
[email protected]cc70f5012013-05-14 04:58:5623using chromeos::FakeCrosDisksClient;
yamaguchicafadf52016-09-15 09:05:5324using chromeos::MountType;
25using chromeos::disks::MountCondition;
[email protected]e3c1fc92012-11-15 00:56:4626
27namespace {
28
yamaguchi934309a2016-10-20 05:07:1229const char kDevice1SourcePath[] = "/device/source_path";
30const char kDevice1MountPath[] = "/device/mount_path";
31const char kDevice2SourcePath[] = "/device/source_path2";
yamaguchi934309a2016-10-20 05:07:1232const char kReadOnlyDeviceMountPath[] = "/device/read_only_mount_path";
33const char kReadOnlyDeviceSourcePath[] = "/device/read_only_source_path";
yamaguchibffc32eb2016-08-17 06:35:3934
[email protected]e3c1fc92012-11-15 00:56:4635// Holds information needed to create a DiskMountManager::Disk instance.
36struct TestDiskInfo {
37 const char* source_path;
38 const char* mount_path;
yamaguchieaaad982016-10-24 09:46:1739 bool write_disabled_by_policy;
[email protected]e3c1fc92012-11-15 00:56:4640 const char* system_path;
41 const char* file_path;
42 const char* device_label;
43 const char* drive_label;
44 const char* vendor_id;
45 const char* vendor_name;
46 const char* product_id;
47 const char* product_name;
48 const char* fs_uuid;
49 const char* system_path_prefix;
50 chromeos::DeviceType device_type;
avi6e1a22d2015-12-21 03:43:2051 uint64_t size_in_bytes;
[email protected]e3c1fc92012-11-15 00:56:4652 bool is_parent;
53 bool is_read_only;
54 bool has_media;
55 bool on_boot_device;
[email protected]79ed457b2014-07-22 04:07:2656 bool on_removable_device;
[email protected]e3c1fc92012-11-15 00:56:4657 bool is_hidden;
58};
59
60// Holds information to create a DiskMOuntManager::MountPointInfo instance.
61struct TestMountPointInfo {
62 const char* source_path;
63 const char* mount_path;
64 chromeos::MountType mount_type;
65 chromeos::disks::MountCondition mount_condition;
66};
67
68// List of disks held in DiskMountManager at the begining of the test.
69const TestDiskInfo kTestDisks[] = {
70 {
yamaguchi934309a2016-10-20 05:07:1271 kDevice1SourcePath,
72 kDevice1MountPath,
yamaguchieaaad982016-10-24 09:46:1773 false, // write_disabled_by_policy
[email protected]e3c1fc92012-11-15 00:56:4674 "/device/prefix/system_path",
75 "/device/file_path",
76 "/device/device_label",
77 "/device/drive_label",
78 "/device/vendor_id",
79 "/device/vendor_name",
80 "/device/product_id",
81 "/device/product_name",
82 "/device/fs_uuid",
83 "/device/prefix",
84 chromeos::DEVICE_TYPE_USB,
85 1073741824, // size in bytes
yamaguchi6594bf7e12016-08-24 22:16:1186 false, // is parent
87 false, // is read only
88 true, // has media
89 false, // is on boot device
90 true, // is on removable device
91 false // is hidden
92 },
93 {
yamaguchi934309a2016-10-20 05:07:1294 kDevice2SourcePath,
yamaguchide59ed62016-11-08 10:07:1095 "", // not mounted initially
yamaguchieaaad982016-10-24 09:46:1796 false, // write_disabled_by_policy
yamaguchi6594bf7e12016-08-24 22:16:1197 "/device/prefix/system_path2",
98 "/device/file_path2",
99 "/device/device_label2",
100 "/device/drive_label2",
101 "/device/vendor_id2",
102 "/device/vendor_name2",
103 "/device/product_id2",
104 "/device/product_name2",
105 "/device/fs_uuid2",
106 "/device/prefix2",
107 chromeos::DEVICE_TYPE_SD,
108 1073741824, // size in bytes
109 false, // is parent
110 false, // is read only
111 true, // has media
112 false, // is on boot device
113 true, // is on removable device
114 false // is hidden
yamaguchibffc32eb2016-08-17 06:35:39115 },
116 {
yamaguchi934309a2016-10-20 05:07:12117 kReadOnlyDeviceSourcePath,
118 kReadOnlyDeviceMountPath,
yamaguchieaaad982016-10-24 09:46:17119 false, // write_disabled_by_policy
yamaguchi6594bf7e12016-08-24 22:16:11120 "/device/prefix/system_path_3",
121 "/device/file_path_3",
122 "/device/device_label_3",
123 "/device/drive_label_3",
124 "/device/vendor_id_3",
125 "/device/vendor_name_3",
126 "/device/product_id_3",
127 "/device/product_name_3",
128 "/device/fs_uuid_3",
yamaguchibffc32eb2016-08-17 06:35:39129 "/device/prefix",
130 chromeos::DEVICE_TYPE_USB,
131 1073741824, // size in bytes
yamaguchi6594bf7e12016-08-24 22:16:11132 false, // is parent
133 true, // is read only
134 true, // has media
135 false, // is on boot device
136 true, // is on removable device
137 false // is hidden
[email protected]e3c1fc92012-11-15 00:56:46138 },
139};
140
[email protected]cc70f5012013-05-14 04:58:56141// List of mount points held in DiskMountManager at the begining of the test.
[email protected]e3c1fc92012-11-15 00:56:46142const TestMountPointInfo kTestMountPoints[] = {
143 {
144 "/archive/source_path",
145 "/archive/mount_path",
146 chromeos::MOUNT_TYPE_ARCHIVE,
147 chromeos::disks::MOUNT_CONDITION_NONE
148 },
149 {
yamaguchi934309a2016-10-20 05:07:12150 kDevice1SourcePath,
151 kDevice1MountPath,
[email protected]e3c1fc92012-11-15 00:56:46152 chromeos::MOUNT_TYPE_DEVICE,
153 chromeos::disks::MOUNT_CONDITION_NONE
154 },
yamaguchibffc32eb2016-08-17 06:35:39155 {
yamaguchi934309a2016-10-20 05:07:12156 kReadOnlyDeviceSourcePath,
157 kReadOnlyDeviceMountPath,
yamaguchibffc32eb2016-08-17 06:35:39158 chromeos::MOUNT_TYPE_DEVICE,
159 chromeos::disks::MOUNT_CONDITION_NONE
160 },
[email protected]e3c1fc92012-11-15 00:56:46161};
162
yamaguchicafadf52016-09-15 09:05:53163// Represents which function in |DiskMountManager::Observer| was invoked.
164enum ObserverEventType {
165 DEVICE_EVENT, // OnDeviceEvent()
166 DISK_EVENT, // OnDiskEvent()
167 FORMAT_EVENT, // OnFormatEvent()
168 MOUNT_EVENT // OnMountEvent()
yamaguchia07c4fb2016-09-14 03:58:03169};
170
yamaguchicafadf52016-09-15 09:05:53171// Represents every event notified to |DiskMountManager::Observer|.
172struct ObserverEvent {
173 public:
174 virtual ObserverEventType type() const = 0;
avi8194ad62016-09-20 16:58:36175 virtual ~ObserverEvent() {}
yamaguchicafadf52016-09-15 09:05:53176};
177
178// Represents an invocation of |DiskMountManager::Observer::OnDeviceEvent()|.
179struct DeviceEvent : public ObserverEvent {
180 DiskMountManager::DeviceEvent event;
181 std::string device_path;
182
183 DeviceEvent() {}
184
185 DeviceEvent(DiskMountManager::DeviceEvent event,
186 const std::string& device_path)
187 : event(event), device_path(device_path) {}
188
189 ObserverEventType type() const override { return DEVICE_EVENT; }
190
191 bool operator==(const DeviceEvent& other) const {
192 return event == other.event && device_path == other.device_path;
193 }
194
195 std::string DebugString() const {
196 return StringPrintf("OnDeviceEvent(%d, %s)", event, device_path.c_str());
197 }
198};
199
200// Represents an invocation of |DiskMountManager::Observer::OnDiskEvent()|.
201struct DiskEvent : public ObserverEvent {
202 DiskMountManager::DiskEvent event;
203 std::unique_ptr<DiskMountManager::Disk> disk;
204
205 DiskEvent(DiskMountManager::DiskEvent event,
206 const DiskMountManager::Disk& disk)
207 : event(event),
208 disk(std::unique_ptr<DiskMountManager::Disk>(
209 new DiskMountManager::Disk(disk))) {}
210
211 DiskEvent(DiskEvent&& other)
212 : event(other.event), disk(std::move(other.disk)) {}
213
214 ObserverEventType type() const override { return DISK_EVENT; }
215
216 bool operator==(const DiskEvent& other) const {
217 return event == other.event && disk == other.disk;
218 }
219
220 std::string DebugString() const {
221 return StringPrintf("OnDiskEvent(event=%d, device_path=%s, mount_path=%s",
222 event, disk->device_path().c_str(),
223 disk->mount_path().c_str());
224 }
225};
226
227// Represents an invocation of |DiskMountManager::Observer::OnFormatEvent()|.
228struct FormatEvent : public ObserverEvent {
229 DiskMountManager::FormatEvent event;
230 chromeos::FormatError error_code;
231 std::string device_path;
232
233 FormatEvent() {}
234 FormatEvent(DiskMountManager::FormatEvent event,
235 chromeos::FormatError error_code,
236 const std::string& device_path)
237 : event(event), error_code(error_code), device_path(device_path) {}
238
239 ObserverEventType type() const override { return FORMAT_EVENT; }
240
241 bool operator==(const FormatEvent& other) const {
242 return event == other.event && error_code == other.error_code &&
243 device_path == other.device_path;
244 }
245
246 std::string DebugString() const {
247 return StringPrintf("OnFormatEvent(%d, %d, %s)", event, error_code,
248 device_path.c_str());
249 }
250};
251
252// Represents an invocation of |DiskMountManager::Observer::OnMountEvent()|.
253struct MountEvent : public ObserverEvent {
254 DiskMountManager::MountEvent event;
255 chromeos::MountError error_code;
256 DiskMountManager::MountPointInfo mount_point;
257
258 // Not passed to callback, but read by handlers. So it's captured upon
259 // callback.
260 std::unique_ptr<DiskMountManager::Disk> disk;
261
262 MountEvent(MountEvent&& other)
263 : event(other.event),
264 error_code(other.error_code),
265 mount_point(other.mount_point),
266 disk(std::move(other.disk)) {}
267 MountEvent(DiskMountManager::MountEvent event,
268 chromeos::MountError error_code,
269 const DiskMountManager::MountPointInfo& mount_point,
270 const DiskMountManager::Disk& disk)
271 : event(event),
272 error_code(error_code),
273 mount_point(mount_point),
274 disk(new DiskMountManager::Disk(disk)) {}
275
276 ObserverEventType type() const override { return MOUNT_EVENT; }
277
278 bool operator==(const MountEvent& other) const;
279
280 std::string DebugString() const {
281 return StringPrintf("OnMountEvent(%d, %d, %s, %s, %d, %d)", event,
282 error_code, mount_point.source_path.c_str(),
283 mount_point.mount_path.c_str(), mount_point.mount_type,
284 mount_point.mount_condition);
285 }
286};
287
288// A mock |Observer| class which records all invocation of the methods invoked
289// from DiskMountManager and all the arguments passed to them.
290class MockDiskMountManagerObserver : public DiskMountManager::Observer {
291 public:
avi8194ad62016-09-20 16:58:36292 explicit MockDiskMountManagerObserver(const DiskMountManager* manager)
yamaguchicafadf52016-09-15 09:05:53293 : manager_(manager) {}
294 ~MockDiskMountManagerObserver() override {}
295
296 // Mock notify methods.
297 void OnDeviceEvent(DiskMountManager::DeviceEvent event,
298 const std::string& device_path) override {
299 events_.push_back(MakeUnique<DeviceEvent>(event, device_path));
300 }
301
302 void OnDiskEvent(DiskMountManager::DiskEvent event,
303 const DiskMountManager::Disk* disk) override {
304 // Take a snapshot (copy) of the Disk object at the time of invocation for
305 // later verification.
306 events_.push_back(MakeUnique<DiskEvent>(event, *disk));
307 }
308
309 void OnFormatEvent(DiskMountManager::FormatEvent event,
310 chromeos::FormatError error_code,
311 const std::string& device_path) override {
312 events_.push_back(MakeUnique<FormatEvent>(event, error_code, device_path));
313 }
314
315 void OnMountEvent(
316 DiskMountManager::MountEvent event,
317 chromeos::MountError error_code,
318 const DiskMountManager::MountPointInfo& mount_point) override {
319 // Take a snapshot (copy) of a Disk object at the time of invocation.
320 // It can be verified later besides the arguments.
321 events_.push_back(MakeUnique<MountEvent>(
322 event, error_code, mount_point,
323 *manager_->disks().find(mount_point.source_path)->second));
324 }
325
326 // Gets invocation history to be verified by testcases.
327 // Verifies if the |index|th invocation is OnDeviceEvent() and returns
328 // details.
329 const DeviceEvent& GetDeviceEvent(size_t index) {
330 DCHECK_GT(events_.size(), index);
331 DCHECK_EQ(DEVICE_EVENT, events_[index]->type());
332 return static_cast<const DeviceEvent&>(*events_[index]);
333 }
334
335 // Verifies if the |index|th invocation is OnDiskEvent() and returns details.
336 const DiskEvent& GetDiskEvent(size_t index) {
337 DCHECK_GT(events_.size(), index);
338 DCHECK_EQ(DISK_EVENT, events_[index]->type());
339 return static_cast<const DiskEvent&>(*events_[index]);
340 }
341
342 // Verifies if the |index|th invocation is OnFormatEvent() and returns
343 // details.
344 const FormatEvent& GetFormatEvent(size_t index) {
345 DCHECK_GT(events_.size(), index);
346 DCHECK_EQ(FORMAT_EVENT, events_[index]->type());
347 return static_cast<const FormatEvent&>(*events_[index]);
348 }
349
350 // Verifies if the |index|th invocation is OnMountEvent() and returns details.
351 const MountEvent& GetMountEvent(size_t index) {
352 DCHECK_GT(events_.size(), index);
353 DCHECK_EQ(MOUNT_EVENT, events_[index]->type());
354 return static_cast<const MountEvent&>(*events_[index]);
355 }
356
357 // Returns number of callback invocations happened so far.
358 size_t GetEventCount() { return events_.size(); }
359
360 // Counts the number of |MountEvent| recorded so far that matches the given
361 // condition.
362 size_t CountMountEvents(DiskMountManager::MountEvent mount_event_type,
363 chromeos::MountError error_code,
364 const std::string& mount_path) {
365 size_t num_matched = 0;
366 for (const auto& it : events_) {
367 if (it->type() != MOUNT_EVENT)
368 continue;
369 const MountEvent& mount_event = static_cast<const MountEvent&>(*it);
370 if (mount_event.event == mount_event_type &&
371 mount_event.error_code == error_code &&
372 mount_event.mount_point.mount_path == mount_path)
373 num_matched++;
374 }
375 return num_matched;
376 }
377
378 // Counts the number of |FormatEvent| recorded so far that matches with
379 // |format_event|.
380 size_t CountFormatEvents(const FormatEvent& exptected_format_event) {
381 size_t num_matched = 0;
382 for (const auto& it : events_) {
383 if (it->type() != FORMAT_EVENT)
384 continue;
385 if (static_cast<const FormatEvent&>(*it) == exptected_format_event)
386 num_matched++;
387 }
388 return num_matched;
389 }
390
391 private:
392 // Pointer to the manager object to which this |Observer| is registered.
393 const DiskMountManager* manager_;
394
395 // Records all invocations.
396 std::vector<std::unique_ptr<ObserverEvent>> events_;
397};
398
399// Shift operators of ostream.
400// Needed to print values in case of EXPECT_* failure in gtest.
401std::ostream& operator<<(std::ostream& stream,
yamaguchicafadf52016-09-15 09:05:53402 const FormatEvent& format_event) {
403 return stream << format_event.DebugString();
404}
405
[email protected]e3c1fc92012-11-15 00:56:46406class DiskMountManagerTest : public testing::Test {
407 public:
kjellanderdae37c42016-09-13 11:10:44408 DiskMountManagerTest() {}
dchengae98daa2015-01-21 20:30:49409 ~DiskMountManagerTest() override {}
[email protected]e3c1fc92012-11-15 00:56:46410
411 // Sets up test dbus tread manager and disks mount manager.
412 // Initializes disk mount manager disks and mount points.
413 // Adds a test observer to the disk mount manager.
dchengae98daa2015-01-21 20:30:49414 void SetUp() override {
[email protected]54652d82013-11-10 16:02:49415 fake_cros_disks_client_ = new FakeCrosDisksClient;
zelidrag29fe3382014-08-27 01:44:48416 DBusThreadManager::GetSetterForTesting()->SetCrosDisksClient(
dcheng0a6e80c2016-04-08 18:37:38417 std::unique_ptr<CrosDisksClient>(fake_cros_disks_client_));
[email protected]e3c1fc92012-11-15 00:56:46418
[email protected]e3c1fc92012-11-15 00:56:46419 DiskMountManager::Initialize();
420
421 InitDisksAndMountPoints();
422
yamaguchicafadf52016-09-15 09:05:53423 observer_.reset(
424 new MockDiskMountManagerObserver(DiskMountManager::GetInstance()));
425 DiskMountManager::GetInstance()->AddObserver(observer_.get());
[email protected]e3c1fc92012-11-15 00:56:46426 }
427
428 // Shuts down dbus thread manager and disk moutn manager used in the test.
dchengae98daa2015-01-21 20:30:49429 void TearDown() override {
yamaguchicafadf52016-09-15 09:05:53430 DiskMountManager::GetInstance()->RemoveObserver(observer_.get());
[email protected]e3c1fc92012-11-15 00:56:46431 DiskMountManager::Shutdown();
432 DBusThreadManager::Shutdown();
433 }
434
435 protected:
436 // Checks if disk mount manager contains a mount point with specified moutn
437 // path.
438 bool HasMountPoint(const std::string& mount_path) {
439 const DiskMountManager::MountPointMap& mount_points =
440 DiskMountManager::GetInstance()->mount_points();
441 return mount_points.find(mount_path) != mount_points.end();
442 }
443
444 private:
445 // Adds a new disk to the disk mount manager.
446 void AddTestDisk(const TestDiskInfo& disk) {
447 EXPECT_TRUE(DiskMountManager::GetInstance()->AddDiskForTest(
avi8194ad62016-09-20 16:58:36448 base::MakeUnique<DiskMountManager::Disk>(
yamaguchieaaad982016-10-24 09:46:17449 disk.source_path, disk.mount_path, disk.write_disabled_by_policy,
450 disk.system_path, disk.file_path, disk.device_label,
451 disk.drive_label, disk.vendor_id, disk.vendor_name, disk.product_id,
452 disk.product_name, disk.fs_uuid, disk.system_path_prefix,
453 disk.device_type, disk.size_in_bytes, disk.is_parent,
454 disk.is_read_only, disk.has_media, disk.on_boot_device,
455 disk.on_removable_device, disk.is_hidden)));
[email protected]e3c1fc92012-11-15 00:56:46456 }
457
458 // Adds a new mount point to the disk mount manager.
459 // If the moutn point is a device mount point, disk with its source path
460 // should already be added to the disk mount manager.
461 void AddTestMountPoint(const TestMountPointInfo& mount_point) {
462 EXPECT_TRUE(DiskMountManager::GetInstance()->AddMountPointForTest(
463 DiskMountManager::MountPointInfo(mount_point.source_path,
464 mount_point.mount_path,
465 mount_point.mount_type,
466 mount_point.mount_condition)));
467 }
468
469 // Adds disks and mount points to disk mount manager.
470 void InitDisksAndMountPoints() {
471 // Disks should be added first (when adding device mount points it is
472 // expected that the corresponding disk is already added).
473 for (size_t i = 0; i < arraysize(kTestDisks); i++)
474 AddTestDisk(kTestDisks[i]);
475
476 for (size_t i = 0; i < arraysize(kTestMountPoints); i++)
477 AddTestMountPoint(kTestMountPoints[i]);
478 }
479
480 protected:
[email protected]cc70f5012013-05-14 04:58:56481 chromeos::FakeCrosDisksClient* fake_cros_disks_client_;
yamaguchicafadf52016-09-15 09:05:53482 std::unique_ptr<MockDiskMountManagerObserver> observer_;
[email protected]df905632013-05-29 23:04:36483 base::MessageLoopForUI message_loop_;
[email protected]e3c1fc92012-11-15 00:56:46484};
485
486// Tests that the observer gets notified on attempt to format non existent mount
487// point.
488TEST_F(DiskMountManagerTest, Format_NotMounted) {
[email protected]e3c1fc92012-11-15 00:56:46489 DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent");
yamaguchicafadf52016-09-15 09:05:53490 ASSERT_EQ(1U, observer_->GetEventCount());
491 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
492 chromeos::FORMAT_ERROR_UNKNOWN, "/mount/non_existent"),
493 observer_->GetFormatEvent(0));
[email protected]e3c1fc92012-11-15 00:56:46494}
495
yamaguchibffc32eb2016-08-17 06:35:39496// Tests that the observer gets notified on attempt to format read-only mount
497// point.
498TEST_F(DiskMountManagerTest, Format_ReadOnly) {
yamaguchi934309a2016-10-20 05:07:12499 DiskMountManager::GetInstance()->FormatMountedDevice(
500 kReadOnlyDeviceMountPath);
yamaguchicafadf52016-09-15 09:05:53501 ASSERT_EQ(1U, observer_->GetEventCount());
502 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
503 chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED,
yamaguchi934309a2016-10-20 05:07:12504 kReadOnlyDeviceMountPath),
yamaguchicafadf52016-09-15 09:05:53505 observer_->GetFormatEvent(0));
yamaguchibffc32eb2016-08-17 06:35:39506}
507
[email protected]e3c1fc92012-11-15 00:56:46508// Tests that it is not possible to format archive mount point.
509TEST_F(DiskMountManagerTest, Format_Archive) {
[email protected]e3c1fc92012-11-15 00:56:46510 DiskMountManager::GetInstance()->FormatMountedDevice("/archive/mount_path");
yamaguchicafadf52016-09-15 09:05:53511 ASSERT_EQ(1U, observer_->GetEventCount());
512 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
513 chromeos::FORMAT_ERROR_UNKNOWN, "/archive/source_path"),
514 observer_->GetFormatEvent(0));
[email protected]e3c1fc92012-11-15 00:56:46515}
516
517// Tests that format fails if the device cannot be unmounted.
518TEST_F(DiskMountManagerTest, Format_FailToUnmount) {
[email protected]e3c1fc92012-11-15 00:56:46519 // Before formatting mounted device, the device should be unmounted.
520 // In this test unmount will fail, and there should be no attempt to
521 // format the device.
[email protected]e3c1fc92012-11-15 00:56:46522
[email protected]cc70f5012013-05-14 04:58:56523 fake_cros_disks_client_->MakeUnmountFail();
[email protected]e3c1fc92012-11-15 00:56:46524 // Start test.
yamaguchi934309a2016-10-20 05:07:12525 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46526
527 // Cros disks will respond asynchronoulsy, so let's drain the message loop.
fdorayf5b47fd12016-09-13 14:12:36528 base::RunLoop().RunUntilIdle();
[email protected]e3c1fc92012-11-15 00:56:46529
yamaguchicafadf52016-09-15 09:05:53530 // Observer should be notified that unmount attempt fails and format task
531 // failed to start.
532 ASSERT_EQ(2U, observer_->GetEventCount());
533 const MountEvent& mount_event = observer_->GetMountEvent(0);
534 EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
535 EXPECT_EQ(chromeos::MOUNT_ERROR_INTERNAL, mount_event.error_code);
yamaguchi934309a2016-10-20 05:07:12536 EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
yamaguchicafadf52016-09-15 09:05:53537
538 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
yamaguchi934309a2016-10-20 05:07:12539 chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53540 observer_->GetFormatEvent(1));
[email protected]cc70f5012013-05-14 04:58:56541 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12542 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56543 fake_cros_disks_client_->last_unmount_device_path());
544 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
545 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35546 EXPECT_EQ(0, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56547
[email protected]e3c1fc92012-11-15 00:56:46548 // The device mount should still be here.
yamaguchi934309a2016-10-20 05:07:12549 EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46550}
551
552// Tests that observer is notified when cros disks fails to start format
553// process.
554TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) {
[email protected]e3c1fc92012-11-15 00:56:46555 // Before formatting mounted device, the device should be unmounted.
[email protected]f026c0f2014-05-06 21:52:35556 // In this test, unmount will succeed, but call to Format method will
[email protected]e3c1fc92012-11-15 00:56:46557 // fail.
[email protected]e3c1fc92012-11-15 00:56:46558
[email protected]f026c0f2014-05-06 21:52:35559 fake_cros_disks_client_->MakeFormatFail();
[email protected]e3c1fc92012-11-15 00:56:46560 // Start the test.
yamaguchi934309a2016-10-20 05:07:12561 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46562
563 // Cros disks will respond asynchronoulsy, so let's drain the message loop.
fdorayf5b47fd12016-09-13 14:12:36564 base::RunLoop().RunUntilIdle();
[email protected]e3c1fc92012-11-15 00:56:46565
yamaguchicafadf52016-09-15 09:05:53566 // Observer should be notified that the device was unmounted and format task
567 // failed to start.
568 ASSERT_EQ(2U, observer_->GetEventCount());
569 const MountEvent& mount_event = observer_->GetMountEvent(0);
570 EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
571 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
yamaguchi934309a2016-10-20 05:07:12572 EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
yamaguchicafadf52016-09-15 09:05:53573
574 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
yamaguchi934309a2016-10-20 05:07:12575 chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53576 observer_->GetFormatEvent(1));
577
[email protected]cc70f5012013-05-14 04:58:56578 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12579 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56580 fake_cros_disks_client_->last_unmount_device_path());
581 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
582 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35583 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
yamaguchi934309a2016-10-20 05:07:12584 EXPECT_EQ(kDevice1SourcePath,
[email protected]f026c0f2014-05-06 21:52:35585 fake_cros_disks_client_->last_format_device_path());
586 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56587
[email protected]e3c1fc92012-11-15 00:56:46588 // The device mount should be gone.
yamaguchi934309a2016-10-20 05:07:12589 EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46590}
591
592// Tests the case where there are two format requests for the same device.
593TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) {
[email protected]8f919ee2013-03-14 19:53:29594 // Only the first format request should be processed (the second unmount
595 // request fails because the device is already unmounted at that point).
[email protected]e3c1fc92012-11-15 00:56:46596 // CrosDisksClient will report that the format process for the first request
597 // is successfully started.
[email protected]e3c1fc92012-11-15 00:56:46598
yamaguchi48ec0aa2016-09-14 10:00:45599 fake_cros_disks_client_->set_unmount_listener(
600 base::Bind(&FakeCrosDisksClient::MakeUnmountFail,
601 base::Unretained(fake_cros_disks_client_)));
602 // Start the test.
yamaguchi934309a2016-10-20 05:07:12603 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
604 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
yamaguchi48ec0aa2016-09-14 10:00:45605
606 // Cros disks will respond asynchronoulsy, so let's drain the message loop.
607 base::RunLoop().RunUntilIdle();
yamaguchia07c4fb2016-09-14 03:58:03608
yamaguchicafadf52016-09-15 09:05:53609 // The observer should get a FORMAT_STARTED event for one format request and a
610 // FORMAT_COMPLETED with an error code for the other format request. The
611 // formatting will be started only for the first request.
612 // There should be only one UNMOUNTING event. The result of the second one
613 // should not be reported as the mount point will go away after the first
614 // request.
615 //
616 // Note that in this test the format completion signal will not be simulated,
617 // so the observer should not get FORMAT_COMPLETED signal.
618
619 ASSERT_EQ(3U, observer_->GetEventCount());
620 const MountEvent& mount_event = observer_->GetMountEvent(0);
621 EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event);
622 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code);
yamaguchi934309a2016-10-20 05:07:12623 EXPECT_EQ(kDevice1MountPath, mount_event.mount_point.mount_path);
yamaguchicafadf52016-09-15 09:05:53624 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
yamaguchi934309a2016-10-20 05:07:12625 chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53626 observer_->GetFormatEvent(1));
627 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED,
yamaguchi934309a2016-10-20 05:07:12628 chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53629 observer_->GetFormatEvent(2));
630
[email protected]cc70f5012013-05-14 04:58:56631 EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12632 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56633 fake_cros_disks_client_->last_unmount_device_path());
634 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
635 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35636 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
yamaguchi934309a2016-10-20 05:07:12637 EXPECT_EQ(kDevice1SourcePath,
[email protected]f026c0f2014-05-06 21:52:35638 fake_cros_disks_client_->last_format_device_path());
[email protected]cc70f5012013-05-14 04:58:56639 EXPECT_EQ("vfat",
[email protected]f026c0f2014-05-06 21:52:35640 fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56641
[email protected]e3c1fc92012-11-15 00:56:46642 // The device mount should be gone.
yamaguchi934309a2016-10-20 05:07:12643 EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46644}
645
yamaguchicafadf52016-09-15 09:05:53646// Verifies a |MountEvent| with the given condition. This function only checks
647// the |mount_path| in |MountPointInfo| to make sure to match the event with
648// preceding mount invocations.
649void VerifyMountEvent(const MountEvent& mount_event,
650 DiskMountManager::MountEvent mount_event_type,
651 chromeos::MountError error_code,
652 const std::string& mount_path) {
653 EXPECT_EQ(mount_event_type, mount_event.event);
654 EXPECT_EQ(error_code, mount_event.error_code);
655 EXPECT_EQ(mount_path, mount_event.mount_point.mount_path);
656}
657
[email protected]e3c1fc92012-11-15 00:56:46658// Tests the case when the format process actually starts and fails.
659TEST_F(DiskMountManagerTest, Format_FormatFails) {
[email protected]f026c0f2014-05-06 21:52:35660 // Both unmount and format device cals are successful in this test.
[email protected]e3c1fc92012-11-15 00:56:46661
[email protected]e3c1fc92012-11-15 00:56:46662 // Start the test.
yamaguchi934309a2016-10-20 05:07:12663 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46664
[email protected]f026c0f2014-05-06 21:52:35665 // Wait for Unmount and Format calls to end.
fdorayf5b47fd12016-09-13 14:12:36666 base::RunLoop().RunUntilIdle();
[email protected]e3c1fc92012-11-15 00:56:46667
[email protected]cc70f5012013-05-14 04:58:56668 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12669 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56670 fake_cros_disks_client_->last_unmount_device_path());
671 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
672 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35673 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
yamaguchi934309a2016-10-20 05:07:12674 EXPECT_EQ(kDevice1SourcePath,
[email protected]f026c0f2014-05-06 21:52:35675 fake_cros_disks_client_->last_format_device_path());
676 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56677
[email protected]e3c1fc92012-11-15 00:56:46678 // The device should be unmounted by now.
yamaguchi934309a2016-10-20 05:07:12679 EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46680
[email protected]a0278d52014-05-06 03:36:15681 // Send failing FORMAT_COMPLETED signal.
[email protected]e3c1fc92012-11-15 00:56:46682 // The failure is marked by ! in fromt of the path (but this should change
683 // soon).
[email protected]a0278d52014-05-06 03:36:15684 fake_cros_disks_client_->SendFormatCompletedEvent(
yamaguchi934309a2016-10-20 05:07:12685 chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath);
yamaguchicafadf52016-09-15 09:05:53686
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,
yamaguchi934309a2016-10-20 05:07:12694 chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
yamaguchicafadf52016-09-15 09:05:53695 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED,
yamaguchi934309a2016-10-20 05:07:12696 chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53697 observer_->GetFormatEvent(1));
698 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
yamaguchi934309a2016-10-20 05:07:12699 chromeos::FORMAT_ERROR_UNKNOWN, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53700 observer_->GetFormatEvent(2));
[email protected]e3c1fc92012-11-15 00:56:46701}
702
[email protected]e3c1fc92012-11-15 00:56:46703// Tests the case when formatting completes successfully.
704TEST_F(DiskMountManagerTest, Format_FormatSuccess) {
705 // Set up cros disks client mocks.
[email protected]f026c0f2014-05-06 21:52:35706 // Both unmount and format device cals are successful in this test.
[email protected]e3c1fc92012-11-15 00:56:46707
[email protected]e3c1fc92012-11-15 00:56:46708 // Start the test.
yamaguchi934309a2016-10-20 05:07:12709 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46710
[email protected]f026c0f2014-05-06 21:52:35711 // Wait for Unmount and Format calls to end.
fdorayf5b47fd12016-09-13 14:12:36712 base::RunLoop().RunUntilIdle();
[email protected]e3c1fc92012-11-15 00:56:46713
[email protected]cc70f5012013-05-14 04:58:56714 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12715 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56716 fake_cros_disks_client_->last_unmount_device_path());
717 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
718 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35719 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
yamaguchi934309a2016-10-20 05:07:12720 EXPECT_EQ(kDevice1SourcePath,
[email protected]f026c0f2014-05-06 21:52:35721 fake_cros_disks_client_->last_format_device_path());
722 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56723
[email protected]e3c1fc92012-11-15 00:56:46724 // The device should be unmounted by now.
yamaguchi934309a2016-10-20 05:07:12725 EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46726
727 // Simulate cros_disks reporting success.
yamaguchi934309a2016-10-20 05:07:12728 fake_cros_disks_client_->SendFormatCompletedEvent(chromeos::FORMAT_ERROR_NONE,
729 kDevice1SourcePath);
yamaguchicafadf52016-09-15 09:05:53730
731 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
732 // events (all of them without an error set).
733 ASSERT_EQ(3U, observer_->GetEventCount());
734 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING,
yamaguchi934309a2016-10-20 05:07:12735 chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
yamaguchicafadf52016-09-15 09:05:53736 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED,
yamaguchi934309a2016-10-20 05:07:12737 chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53738 observer_->GetFormatEvent(1));
739 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED,
yamaguchi934309a2016-10-20 05:07:12740 chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath),
yamaguchicafadf52016-09-15 09:05:53741 observer_->GetFormatEvent(2));
[email protected]e3c1fc92012-11-15 00:56:46742}
743
744// Tests that it's possible to format the device twice in a row (this may not be
745// true if the list of pending formats is not properly cleared).
746TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) {
[email protected]f026c0f2014-05-06 21:52:35747 // All unmount and format device cals are successful in this test.
[email protected]e3c1fc92012-11-15 00:56:46748 // Each of the should be made twice (once for each formatting task).
[email protected]e3c1fc92012-11-15 00:56:46749
[email protected]e3c1fc92012-11-15 00:56:46750 // Start the test.
yamaguchi934309a2016-10-20 05:07:12751 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46752
[email protected]f026c0f2014-05-06 21:52:35753 // Wait for Unmount and Format calls to end.
fdorayf5b47fd12016-09-13 14:12:36754 base::RunLoop().RunUntilIdle();
[email protected]e3c1fc92012-11-15 00:56:46755
[email protected]cc70f5012013-05-14 04:58:56756 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12757 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56758 fake_cros_disks_client_->last_unmount_device_path());
759 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
760 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35761 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
yamaguchi934309a2016-10-20 05:07:12762 EXPECT_EQ(kDevice1SourcePath,
[email protected]f026c0f2014-05-06 21:52:35763 fake_cros_disks_client_->last_format_device_path());
764 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56765
[email protected]e3c1fc92012-11-15 00:56:46766 // The device should be unmounted by now.
yamaguchi934309a2016-10-20 05:07:12767 EXPECT_FALSE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46768
769 // Simulate cros_disks reporting success.
yamaguchi934309a2016-10-20 05:07:12770 fake_cros_disks_client_->SendFormatCompletedEvent(chromeos::FORMAT_ERROR_NONE,
771 kDevice1SourcePath);
[email protected]e3c1fc92012-11-15 00:56:46772
773 // Simulate the device remounting.
[email protected]cc70f5012013-05-14 04:58:56774 fake_cros_disks_client_->SendMountCompletedEvent(
yamaguchi934309a2016-10-20 05:07:12775 chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath,
776 chromeos::MOUNT_TYPE_DEVICE, kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46777
yamaguchi934309a2016-10-20 05:07:12778 EXPECT_TRUE(HasMountPoint(kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46779
780 // Try formatting again.
yamaguchi934309a2016-10-20 05:07:12781 DiskMountManager::GetInstance()->FormatMountedDevice(kDevice1MountPath);
[email protected]e3c1fc92012-11-15 00:56:46782
[email protected]f026c0f2014-05-06 21:52:35783 // Wait for Unmount and Format calls to end.
fdorayf5b47fd12016-09-13 14:12:36784 base::RunLoop().RunUntilIdle();
[email protected]e3c1fc92012-11-15 00:56:46785
[email protected]cc70f5012013-05-14 04:58:56786 EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
yamaguchi934309a2016-10-20 05:07:12787 EXPECT_EQ(kDevice1MountPath,
[email protected]cc70f5012013-05-14 04:58:56788 fake_cros_disks_client_->last_unmount_device_path());
789 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
790 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35791 EXPECT_EQ(2, fake_cros_disks_client_->format_call_count());
yamaguchi934309a2016-10-20 05:07:12792 EXPECT_EQ(kDevice1SourcePath,
[email protected]f026c0f2014-05-06 21:52:35793 fake_cros_disks_client_->last_format_device_path());
794 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56795
[email protected]e3c1fc92012-11-15 00:56:46796 // Simulate cros_disks reporting success.
yamaguchi934309a2016-10-20 05:07:12797 fake_cros_disks_client_->SendFormatCompletedEvent(chromeos::FORMAT_ERROR_NONE,
798 kDevice1SourcePath);
yamaguchicafadf52016-09-15 09:05:53799
800 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
801 // events (all of them without an error set) twice (once for each formatting
802 // task).
803 // Also, there should be a MOUNTING event when the device remounting is
804 // simulated.
805 EXPECT_EQ(7U, observer_->GetEventCount());
806
807 EXPECT_EQ(2U, observer_->CountFormatEvents(FormatEvent(
808 DiskMountManager::FORMAT_COMPLETED,
yamaguchi934309a2016-10-20 05:07:12809 chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath)));
yamaguchicafadf52016-09-15 09:05:53810
811 EXPECT_EQ(2U, observer_->CountFormatEvents(FormatEvent(
812 DiskMountManager::FORMAT_STARTED,
yamaguchi934309a2016-10-20 05:07:12813 chromeos::FORMAT_ERROR_NONE, kDevice1SourcePath)));
yamaguchicafadf52016-09-15 09:05:53814
815 EXPECT_EQ(2U, observer_->CountMountEvents(DiskMountManager::UNMOUNTING,
816 chromeos::MOUNT_ERROR_NONE,
yamaguchi934309a2016-10-20 05:07:12817 kDevice1MountPath));
yamaguchicafadf52016-09-15 09:05:53818
819 EXPECT_EQ(1U, observer_->CountMountEvents(DiskMountManager::MOUNTING,
820 chromeos::MOUNT_ERROR_NONE,
yamaguchi934309a2016-10-20 05:07:12821 kDevice1MountPath));
[email protected]e3c1fc92012-11-15 00:56:46822}
823
yamaguchi6594bf7e12016-08-24 22:16:11824TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) {
825 DiskMountManager* manager = DiskMountManager::GetInstance();
yamaguchi934309a2016-10-20 05:07:12826 const std::string kSourcePath1 = kDevice1SourcePath;
827 const std::string kSourcePath2 = kDevice2SourcePath;
yamaguchi6594bf7e12016-08-24 22:16:11828 const std::string kSourceFormat = std::string();
829 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE
830 // For MountCompleted. Must be non-empty strings.
831 const std::string kMountPath1 = "/media/foo";
832 const std::string kMountPath2 = "/media/bar";
833
yamaguchi6594bf7e12016-08-24 22:16:11834 manager->MountPath(kSourcePath1, kSourceFormat, std::string(),
835 chromeos::MOUNT_TYPE_DEVICE,
836 chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
837 manager->MountPath(kSourcePath2, kSourceFormat, std::string(),
838 chromeos::MOUNT_TYPE_DEVICE,
839 chromeos::MOUNT_ACCESS_MODE_READ_ONLY);
840 // Simulate cros_disks reporting mount completed.
841 fake_cros_disks_client_->SendMountCompletedEvent(
842 chromeos::MOUNT_ERROR_NONE, kSourcePath1, chromeos::MOUNT_TYPE_DEVICE,
843 kMountPath1);
844 fake_cros_disks_client_->SendMountCompletedEvent(
845 chromeos::MOUNT_ERROR_NONE, kSourcePath2, chromeos::MOUNT_TYPE_DEVICE,
846 kMountPath2);
847
yamaguchicafadf52016-09-15 09:05:53848 // Event handlers of observers should be called.
849 ASSERT_EQ(2U, observer_->GetEventCount());
850 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
851 chromeos::MOUNT_ERROR_NONE, kMountPath1);
852 // For the 2nd source, the disk (block device) is not read-only but the
853 // test will mount it in read-only mode.
854 // Observers query |disks_| from |DiskMountManager| in its event handler for
855 // a mount completion event. Therefore |disks_| must be updated with correct
856 // |read_only| value before notifying to observers.
857 const MountEvent& secondMountEvent = observer_->GetMountEvent(1);
858 EXPECT_EQ(DiskMountManager::MOUNTING, secondMountEvent.event);
859 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, secondMountEvent.error_code);
860 EXPECT_EQ(kMountPath2, secondMountEvent.mount_point.mount_path);
861 // Verify if the disk appears read-only at the time of notification to
862 // observers.
863 EXPECT_TRUE(secondMountEvent.disk->is_read_only());
864
865 // Verify the final state of manager->disks.
yamaguchi6594bf7e12016-08-24 22:16:11866 const DiskMountManager::DiskMap& disks = manager->disks();
867 ASSERT_GT(disks.count(kSourcePath1), 0U);
868 EXPECT_FALSE(disks.find(kSourcePath1)->second->is_read_only());
869 ASSERT_GT(disks.count(kSourcePath2), 0U);
870 EXPECT_TRUE(disks.find(kSourcePath2)->second->is_read_only());
871}
872
yamaguchi21448d5b2016-09-06 02:04:56873TEST_F(DiskMountManagerTest, MountPath_ReadOnlyDevice) {
874 DiskMountManager* manager = DiskMountManager::GetInstance();
875 const std::string kSourceFormat = std::string();
876 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE
877
yamaguchi21448d5b2016-09-06 02:04:56878 // Attempt to mount a read-only device in read-write mode.
yamaguchi934309a2016-10-20 05:07:12879 manager->MountPath(kReadOnlyDeviceSourcePath, kSourceFormat, std::string(),
yamaguchi21448d5b2016-09-06 02:04:56880 chromeos::MOUNT_TYPE_DEVICE,
881 chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
882 // Simulate cros_disks reporting mount completed.
883 fake_cros_disks_client_->SendMountCompletedEvent(
yamaguchi934309a2016-10-20 05:07:12884 chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceSourcePath,
885 chromeos::MOUNT_TYPE_DEVICE, kReadOnlyDeviceMountPath);
yamaguchi21448d5b2016-09-06 02:04:56886
yamaguchicafadf52016-09-15 09:05:53887 // Event handlers of observers should be called.
888 ASSERT_EQ(1U, observer_->GetEventCount());
889 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
yamaguchi934309a2016-10-20 05:07:12890 chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceMountPath);
yamaguchi21448d5b2016-09-06 02:04:56891 const DiskMountManager::DiskMap& disks = manager->disks();
yamaguchi934309a2016-10-20 05:07:12892 ASSERT_GT(disks.count(kReadOnlyDeviceSourcePath), 0U);
yamaguchi21448d5b2016-09-06 02:04:56893 // The mounted disk should preserve the read-only flag of the block device.
yamaguchi934309a2016-10-20 05:07:12894 EXPECT_TRUE(disks.find(kReadOnlyDeviceSourcePath)->second->is_read_only());
yamaguchi21448d5b2016-09-06 02:04:56895}
896
yamaguchide59ed62016-11-08 10:07:10897TEST_F(DiskMountManagerTest, RemountRemovableDrives) {
898 DiskMountManager* manager = DiskMountManager::GetInstance();
899 // Initially we have 2 mounted devices.
900 // kDevice1MountPath --- read-write device, mounted in read-write mode.
901 // kReadOnlyDeviceMountPath --- read-only device, mounted in read-only mode.
902
903 manager->RemountAllRemovableDrives(chromeos::MOUNT_ACCESS_MODE_READ_ONLY);
904
905 // Simulate cros_disks reporting mount completed.
906 fake_cros_disks_client_->SendMountCompletedEvent(
907 chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath,
908 chromeos::MOUNT_TYPE_DEVICE, kDevice1MountPath);
909
910 // Should remount disks that are not read-only by its hardware device.
911 ASSERT_EQ(1U, observer_->GetEventCount());
912 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING,
913 chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
914 // The disk is remounted in read-only mode.
915 EXPECT_TRUE(
916 manager->FindDiskBySourcePath(kDevice1SourcePath)->is_read_only());
917 // Remounted disk should also appear as read-only to observers.
918 EXPECT_TRUE(observer_->GetMountEvent(0).disk->is_read_only());
919
920 // Remount in read-write mode again.
921 manager->RemountAllRemovableDrives(chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
922
923 // Simulate cros_disks reporting mount completed.
924 fake_cros_disks_client_->SendMountCompletedEvent(
925 chromeos::MOUNT_ERROR_NONE, kDevice1SourcePath,
926 chromeos::MOUNT_TYPE_DEVICE, kDevice1MountPath);
927 // Event handlers of observers should be called.
928 ASSERT_EQ(2U, observer_->GetEventCount());
929 VerifyMountEvent(observer_->GetMountEvent(1), DiskMountManager::MOUNTING,
930 chromeos::MOUNT_ERROR_NONE, kDevice1MountPath);
931 // The read-write device should be remounted in read-write mode.
932 EXPECT_FALSE(
933 manager->FindDiskBySourcePath(kDevice1SourcePath)->is_read_only());
934 // Remounted disk should also appear as writable to observers.
935 EXPECT_FALSE(observer_->GetMountEvent(1).disk->is_read_only());
936}
937
[email protected]e3c1fc92012-11-15 00:56:46938} // namespace