blob: 03f0d56c4c146a570223658a88e80b72852e3dba [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"
[email protected]f129d2502013-07-17 22:45:509#include "base/message_loop/message_loop.h"
zelidrag29fe3382014-08-27 01:44:4810#include "chromeos/dbus/dbus_thread_manager.h"
[email protected]cc70f5012013-05-14 04:58:5611#include "chromeos/dbus/fake_cros_disks_client.h"
[email protected]e3c1fc92012-11-15 00:56:4612#include "chromeos/disks/disk_mount_manager.h"
kjellanderdae37c42016-09-13 11:10:4413#include "testing/gmock/include/gmock/gmock.h"
[email protected]e3c1fc92012-11-15 00:56:4614#include "testing/gtest/include/gtest/gtest.h"
15
16using chromeos::disks::DiskMountManager;
17using chromeos::CrosDisksClient;
18using chromeos::DBusThreadManager;
[email protected]cc70f5012013-05-14 04:58:5619using chromeos::FakeCrosDisksClient;
kjellanderdae37c42016-09-13 11:10:4420using testing::_;
21using testing::Field;
22using testing::InSequence;
23using testing::InvokeWithoutArgs;
[email protected]e3c1fc92012-11-15 00:56:4624
25namespace {
26
yamaguchibffc32eb2016-08-17 06:35:3927const char kReadOnlyMountpath[] = "/device/read_only_mount_path";
28const char kReadOnlyDeviceSource[] = "/device/read_only_source_path";
29
[email protected]e3c1fc92012-11-15 00:56:4630// Holds information needed to create a DiskMountManager::Disk instance.
31struct TestDiskInfo {
32 const char* source_path;
33 const char* mount_path;
34 const char* system_path;
35 const char* file_path;
36 const char* device_label;
37 const char* drive_label;
38 const char* vendor_id;
39 const char* vendor_name;
40 const char* product_id;
41 const char* product_name;
42 const char* fs_uuid;
43 const char* system_path_prefix;
44 chromeos::DeviceType device_type;
avi6e1a22d2015-12-21 03:43:2045 uint64_t size_in_bytes;
[email protected]e3c1fc92012-11-15 00:56:4646 bool is_parent;
47 bool is_read_only;
48 bool has_media;
49 bool on_boot_device;
[email protected]79ed457b2014-07-22 04:07:2650 bool on_removable_device;
[email protected]e3c1fc92012-11-15 00:56:4651 bool is_hidden;
52};
53
54// Holds information to create a DiskMOuntManager::MountPointInfo instance.
55struct TestMountPointInfo {
56 const char* source_path;
57 const char* mount_path;
58 chromeos::MountType mount_type;
59 chromeos::disks::MountCondition mount_condition;
60};
61
62// List of disks held in DiskMountManager at the begining of the test.
63const TestDiskInfo kTestDisks[] = {
64 {
65 "/device/source_path",
66 "/device/mount_path",
67 "/device/prefix/system_path",
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 chromeos::DEVICE_TYPE_USB,
78 1073741824, // size in bytes
yamaguchi6594bf7e12016-08-24 22:16:1179 false, // is parent
80 false, // is read only
81 true, // has media
82 false, // is on boot device
83 true, // is on removable device
84 false // is hidden
85 },
86 {
87 "/device/source_path2",
88 "/device/mount_path2",
89 "/device/prefix/system_path2",
90 "/device/file_path2",
91 "/device/device_label2",
92 "/device/drive_label2",
93 "/device/vendor_id2",
94 "/device/vendor_name2",
95 "/device/product_id2",
96 "/device/product_name2",
97 "/device/fs_uuid2",
98 "/device/prefix2",
99 chromeos::DEVICE_TYPE_SD,
100 1073741824, // size in bytes
101 false, // is parent
102 false, // is read only
103 true, // has media
104 false, // is on boot device
105 true, // is on removable device
106 false // is hidden
yamaguchibffc32eb2016-08-17 06:35:39107 },
108 {
109 kReadOnlyDeviceSource,
110 kReadOnlyMountpath,
yamaguchi6594bf7e12016-08-24 22:16:11111 "/device/prefix/system_path_3",
112 "/device/file_path_3",
113 "/device/device_label_3",
114 "/device/drive_label_3",
115 "/device/vendor_id_3",
116 "/device/vendor_name_3",
117 "/device/product_id_3",
118 "/device/product_name_3",
119 "/device/fs_uuid_3",
yamaguchibffc32eb2016-08-17 06:35:39120 "/device/prefix",
121 chromeos::DEVICE_TYPE_USB,
122 1073741824, // size in bytes
yamaguchi6594bf7e12016-08-24 22:16:11123 false, // is parent
124 true, // is read only
125 true, // has media
126 false, // is on boot device
127 true, // is on removable device
128 false // is hidden
[email protected]e3c1fc92012-11-15 00:56:46129 },
130};
131
[email protected]cc70f5012013-05-14 04:58:56132// List of mount points held in DiskMountManager at the begining of the test.
[email protected]e3c1fc92012-11-15 00:56:46133const TestMountPointInfo kTestMountPoints[] = {
134 {
135 "/archive/source_path",
136 "/archive/mount_path",
137 chromeos::MOUNT_TYPE_ARCHIVE,
138 chromeos::disks::MOUNT_CONDITION_NONE
139 },
140 {
141 "/device/source_path",
142 "/device/mount_path",
143 chromeos::MOUNT_TYPE_DEVICE,
144 chromeos::disks::MOUNT_CONDITION_NONE
145 },
yamaguchibffc32eb2016-08-17 06:35:39146 {
147 kReadOnlyDeviceSource,
148 kReadOnlyMountpath,
149 chromeos::MOUNT_TYPE_DEVICE,
150 chromeos::disks::MOUNT_CONDITION_NONE
151 },
[email protected]e3c1fc92012-11-15 00:56:46152};
153
kjellanderdae37c42016-09-13 11:10:44154// Mocks DiskMountManager observer.
yamaguchi7bec88d82016-09-13 06:10:37155class MockDiskMountManagerObserver : public DiskMountManager::Observer {
156 public:
kjellanderdae37c42016-09-13 11:10:44157 virtual ~MockDiskMountManagerObserver() {}
yamaguchi7bec88d82016-09-13 06:10:37158
kjellanderdae37c42016-09-13 11:10:44159 MOCK_METHOD2(OnDiskEvent, void(DiskMountManager::DiskEvent event,
160 const DiskMountManager::Disk* disk));
161 MOCK_METHOD2(OnDeviceEvent, void(DiskMountManager::DeviceEvent event,
162 const std::string& device_path));
163 MOCK_METHOD3(OnMountEvent,
164 void(DiskMountManager::MountEvent event,
165 chromeos::MountError error_code,
166 const DiskMountManager::MountPointInfo& mount_point));
167 MOCK_METHOD3(OnFormatEvent,
168 void(DiskMountManager::FormatEvent event,
169 chromeos::FormatError error_code,
170 const std::string& device_path));
yamaguchi7bec88d82016-09-13 06:10:37171};
172
kjellanderdae37c42016-09-13 11:10:44173// Expect |is_read_only| value of a disk object keyed by |source_path|.
174void ExpectDiskReadOnly(const DiskMountManager* manager,
175 const std::string& source_path,
176 bool expected) {
177 EXPECT_EQ(expected,
178 manager->disks().find(source_path)->second->is_read_only());
yamaguchi6594bf7e12016-08-24 22:16:11179}
180
[email protected]e3c1fc92012-11-15 00:56:46181class DiskMountManagerTest : public testing::Test {
182 public:
kjellanderdae37c42016-09-13 11:10:44183 DiskMountManagerTest() {}
dchengae98daa2015-01-21 20:30:49184 ~DiskMountManagerTest() override {}
[email protected]e3c1fc92012-11-15 00:56:46185
186 // Sets up test dbus tread manager and disks mount manager.
187 // Initializes disk mount manager disks and mount points.
188 // Adds a test observer to the disk mount manager.
dchengae98daa2015-01-21 20:30:49189 void SetUp() override {
[email protected]54652d82013-11-10 16:02:49190 fake_cros_disks_client_ = new FakeCrosDisksClient;
zelidrag29fe3382014-08-27 01:44:48191 DBusThreadManager::GetSetterForTesting()->SetCrosDisksClient(
dcheng0a6e80c2016-04-08 18:37:38192 std::unique_ptr<CrosDisksClient>(fake_cros_disks_client_));
[email protected]e3c1fc92012-11-15 00:56:46193
[email protected]e3c1fc92012-11-15 00:56:46194 DiskMountManager::Initialize();
195
196 InitDisksAndMountPoints();
197
kjellanderdae37c42016-09-13 11:10:44198 DiskMountManager::GetInstance()->AddObserver(&observer_);
[email protected]e3c1fc92012-11-15 00:56:46199 }
200
201 // Shuts down dbus thread manager and disk moutn manager used in the test.
dchengae98daa2015-01-21 20:30:49202 void TearDown() override {
kjellanderdae37c42016-09-13 11:10:44203 DiskMountManager::GetInstance()->RemoveObserver(&observer_);
[email protected]e3c1fc92012-11-15 00:56:46204 DiskMountManager::Shutdown();
205 DBusThreadManager::Shutdown();
206 }
207
208 protected:
209 // Checks if disk mount manager contains a mount point with specified moutn
210 // path.
211 bool HasMountPoint(const std::string& mount_path) {
212 const DiskMountManager::MountPointMap& mount_points =
213 DiskMountManager::GetInstance()->mount_points();
214 return mount_points.find(mount_path) != mount_points.end();
215 }
216
217 private:
218 // Adds a new disk to the disk mount manager.
219 void AddTestDisk(const TestDiskInfo& disk) {
220 EXPECT_TRUE(DiskMountManager::GetInstance()->AddDiskForTest(
221 new DiskMountManager::Disk(disk.source_path,
222 disk.mount_path,
223 disk.system_path,
224 disk.file_path,
225 disk.device_label,
226 disk.drive_label,
227 disk.vendor_id,
228 disk.vendor_name,
229 disk.product_id,
230 disk.product_name,
231 disk.fs_uuid,
232 disk.system_path_prefix,
233 disk.device_type,
234 disk.size_in_bytes,
235 disk.is_parent,
236 disk.is_read_only,
237 disk.has_media,
238 disk.on_boot_device,
[email protected]79ed457b2014-07-22 04:07:26239 disk.on_removable_device,
[email protected]e3c1fc92012-11-15 00:56:46240 disk.is_hidden)));
241 }
242
243 // Adds a new mount point to the disk mount manager.
244 // If the moutn point is a device mount point, disk with its source path
245 // should already be added to the disk mount manager.
246 void AddTestMountPoint(const TestMountPointInfo& mount_point) {
247 EXPECT_TRUE(DiskMountManager::GetInstance()->AddMountPointForTest(
248 DiskMountManager::MountPointInfo(mount_point.source_path,
249 mount_point.mount_path,
250 mount_point.mount_type,
251 mount_point.mount_condition)));
252 }
253
254 // Adds disks and mount points to disk mount manager.
255 void InitDisksAndMountPoints() {
256 // Disks should be added first (when adding device mount points it is
257 // expected that the corresponding disk is already added).
258 for (size_t i = 0; i < arraysize(kTestDisks); i++)
259 AddTestDisk(kTestDisks[i]);
260
261 for (size_t i = 0; i < arraysize(kTestMountPoints); i++)
262 AddTestMountPoint(kTestMountPoints[i]);
263 }
264
265 protected:
[email protected]cc70f5012013-05-14 04:58:56266 chromeos::FakeCrosDisksClient* fake_cros_disks_client_;
kjellanderdae37c42016-09-13 11:10:44267 MockDiskMountManagerObserver observer_;
[email protected]df905632013-05-29 23:04:36268 base::MessageLoopForUI message_loop_;
[email protected]e3c1fc92012-11-15 00:56:46269};
270
271// Tests that the observer gets notified on attempt to format non existent mount
272// point.
273TEST_F(DiskMountManagerTest, Format_NotMounted) {
kjellanderdae37c42016-09-13 11:10:44274 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
275 chromeos::FORMAT_ERROR_UNKNOWN,
276 "/mount/non_existent"))
277 .Times(1);
[email protected]e3c1fc92012-11-15 00:56:46278 DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent");
279}
280
yamaguchibffc32eb2016-08-17 06:35:39281// Tests that the observer gets notified on attempt to format read-only mount
282// point.
283TEST_F(DiskMountManagerTest, Format_ReadOnly) {
kjellanderdae37c42016-09-13 11:10:44284 EXPECT_CALL(observer_,
285 OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
286 chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED,
287 kReadOnlyMountpath))
288 .Times(1);
yamaguchibffc32eb2016-08-17 06:35:39289 DiskMountManager::GetInstance()->FormatMountedDevice(kReadOnlyMountpath);
290}
291
[email protected]e3c1fc92012-11-15 00:56:46292// Tests that it is not possible to format archive mount point.
293TEST_F(DiskMountManagerTest, Format_Archive) {
kjellanderdae37c42016-09-13 11:10:44294 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
295 chromeos::FORMAT_ERROR_UNKNOWN,
296 "/archive/source_path"))
297 .Times(1);
298
[email protected]e3c1fc92012-11-15 00:56:46299 DiskMountManager::GetInstance()->FormatMountedDevice("/archive/mount_path");
300}
301
302// Tests that format fails if the device cannot be unmounted.
303TEST_F(DiskMountManagerTest, Format_FailToUnmount) {
[email protected]e3c1fc92012-11-15 00:56:46304 // Before formatting mounted device, the device should be unmounted.
305 // In this test unmount will fail, and there should be no attempt to
306 // format the device.
[email protected]e3c1fc92012-11-15 00:56:46307
kjellanderdae37c42016-09-13 11:10:44308 // Set up expectations for observer mock.
309 // Observer should be notified that unmount attempt fails and format task
310 // failed to start.
311 {
312 InSequence s;
313
314 EXPECT_CALL(observer_,
315 OnMountEvent(DiskMountManager::UNMOUNTING,
316 chromeos::MOUNT_ERROR_INTERNAL,
317 Field(&DiskMountManager::MountPointInfo::mount_path,
318 "/device/mount_path")))
319 .Times(1);
320
321 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
322 chromeos::FORMAT_ERROR_UNKNOWN,
323 "/device/source_path"))
324 .Times(1);
325 }
326
[email protected]cc70f5012013-05-14 04:58:56327 fake_cros_disks_client_->MakeUnmountFail();
[email protected]e3c1fc92012-11-15 00:56:46328 // Start test.
329 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
330
331 // Cros disks will respond asynchronoulsy, so let's drain the message loop.
332 message_loop_.RunUntilIdle();
333
[email protected]cc70f5012013-05-14 04:58:56334 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
335 EXPECT_EQ("/device/mount_path",
336 fake_cros_disks_client_->last_unmount_device_path());
337 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
338 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35339 EXPECT_EQ(0, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56340
[email protected]e3c1fc92012-11-15 00:56:46341 // The device mount should still be here.
342 EXPECT_TRUE(HasMountPoint("/device/mount_path"));
343}
344
345// Tests that observer is notified when cros disks fails to start format
346// process.
347TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) {
[email protected]e3c1fc92012-11-15 00:56:46348 // Before formatting mounted device, the device should be unmounted.
[email protected]f026c0f2014-05-06 21:52:35349 // In this test, unmount will succeed, but call to Format method will
[email protected]e3c1fc92012-11-15 00:56:46350 // fail.
[email protected]e3c1fc92012-11-15 00:56:46351
kjellanderdae37c42016-09-13 11:10:44352 // Set up expectations for observer mock.
353 // Observer should be notified that the device was unmounted and format task
354 // failed to start.
355 {
356 InSequence s;
357
358 EXPECT_CALL(observer_,
359 OnMountEvent(DiskMountManager::UNMOUNTING,
360 chromeos::MOUNT_ERROR_NONE,
361 Field(&DiskMountManager::MountPointInfo::mount_path,
362 "/device/mount_path")))
363 .Times(1);
364
365 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
366 chromeos::FORMAT_ERROR_UNKNOWN,
367 "/device/source_path"))
368 .Times(1);
369 }
370
[email protected]f026c0f2014-05-06 21:52:35371 fake_cros_disks_client_->MakeFormatFail();
[email protected]e3c1fc92012-11-15 00:56:46372 // Start the test.
373 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
374
375 // Cros disks will respond asynchronoulsy, so let's drain the message loop.
376 message_loop_.RunUntilIdle();
377
[email protected]cc70f5012013-05-14 04:58:56378 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
379 EXPECT_EQ("/device/mount_path",
380 fake_cros_disks_client_->last_unmount_device_path());
381 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
382 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35383 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56384 EXPECT_EQ("/device/source_path",
[email protected]f026c0f2014-05-06 21:52:35385 fake_cros_disks_client_->last_format_device_path());
386 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56387
[email protected]e3c1fc92012-11-15 00:56:46388 // The device mount should be gone.
389 EXPECT_FALSE(HasMountPoint("/device/mount_path"));
390}
391
392// Tests the case where there are two format requests for the same device.
393TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) {
[email protected]8f919ee2013-03-14 19:53:29394 // Only the first format request should be processed (the second unmount
395 // request fails because the device is already unmounted at that point).
[email protected]e3c1fc92012-11-15 00:56:46396 // CrosDisksClient will report that the format process for the first request
397 // is successfully started.
[email protected]e3c1fc92012-11-15 00:56:46398
kjellanderdae37c42016-09-13 11:10:44399 // Set up expectations for observer mock.
yamaguchi7bec88d82016-09-13 06:10:37400 // The observer should get a FORMAT_STARTED event for one format request and a
401 // FORMAT_COMPLETED with an error code for the other format request. The
402 // formatting will be started only for the first request.
403 // There should be only one UNMOUNTING event. The result of the second one
404 // should not be reported as the mount point will go away after the first
405 // request.
406 //
407 // Note that in this test the format completion signal will not be simulated,
408 // so the observer should not get FORMAT_COMPLETED signal.
kjellanderdae37c42016-09-13 11:10:44409 {
410 InSequence s;
yamaguchi7bec88d82016-09-13 06:10:37411
kjellanderdae37c42016-09-13 11:10:44412 EXPECT_CALL(observer_,
413 OnMountEvent(DiskMountManager::UNMOUNTING,
414 chromeos::MOUNT_ERROR_NONE,
415 Field(&DiskMountManager::MountPointInfo::mount_path,
416 "/device/mount_path")))
417 .Times(1);
418
419 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
420 chromeos::FORMAT_ERROR_UNKNOWN,
421 "/device/source_path"))
422 .Times(1);
423
424 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
425 chromeos::FORMAT_ERROR_NONE,
426 "/device/source_path"))
427 .Times(1);
428 }
429
430 fake_cros_disks_client_->set_unmount_listener(
431 base::Bind(&FakeCrosDisksClient::MakeUnmountFail,
432 base::Unretained(fake_cros_disks_client_)));
433 // Start the test.
434 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
435 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
436
437 // Cros disks will respond asynchronoulsy, so let's drain the message loop.
438 message_loop_.RunUntilIdle();
yamaguchi7bec88d82016-09-13 06:10:37439
[email protected]cc70f5012013-05-14 04:58:56440 EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
441 EXPECT_EQ("/device/mount_path",
442 fake_cros_disks_client_->last_unmount_device_path());
443 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
444 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35445 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56446 EXPECT_EQ("/device/source_path",
[email protected]f026c0f2014-05-06 21:52:35447 fake_cros_disks_client_->last_format_device_path());
[email protected]cc70f5012013-05-14 04:58:56448 EXPECT_EQ("vfat",
[email protected]f026c0f2014-05-06 21:52:35449 fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56450
[email protected]e3c1fc92012-11-15 00:56:46451 // The device mount should be gone.
452 EXPECT_FALSE(HasMountPoint("/device/mount_path"));
453}
454
455// Tests the case when the format process actually starts and fails.
456TEST_F(DiskMountManagerTest, Format_FormatFails) {
[email protected]f026c0f2014-05-06 21:52:35457 // Both unmount and format device cals are successful in this test.
[email protected]e3c1fc92012-11-15 00:56:46458
kjellanderdae37c42016-09-13 11:10:44459 // Set up expectations for observer mock.
460 // The observer should get notified that the device was unmounted and that
461 // formatting has started.
462 // After the formatting starts, the test will simulate failing
463 // FORMAT_COMPLETED signal, so the observer should also be notified the
464 // formatting has failed (FORMAT_COMPLETED event).
465 {
466 InSequence s;
467
468 EXPECT_CALL(observer_,
469 OnMountEvent(DiskMountManager::UNMOUNTING,
470 chromeos::MOUNT_ERROR_NONE,
471 Field(&DiskMountManager::MountPointInfo::mount_path,
472 "/device/mount_path")))
473 .Times(1);
474
475 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
476 chromeos::FORMAT_ERROR_NONE,
477 "/device/source_path"))
478 .Times(1);
479
480 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
481 chromeos::FORMAT_ERROR_UNKNOWN,
482 "/device/source_path"))
483 .Times(1);
484 }
485
[email protected]e3c1fc92012-11-15 00:56:46486 // Start the test.
487 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
488
[email protected]f026c0f2014-05-06 21:52:35489 // Wait for Unmount and Format calls to end.
[email protected]e3c1fc92012-11-15 00:56:46490 message_loop_.RunUntilIdle();
491
[email protected]cc70f5012013-05-14 04:58:56492 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
493 EXPECT_EQ("/device/mount_path",
494 fake_cros_disks_client_->last_unmount_device_path());
495 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
496 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35497 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56498 EXPECT_EQ("/device/source_path",
[email protected]f026c0f2014-05-06 21:52:35499 fake_cros_disks_client_->last_format_device_path());
500 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56501
[email protected]e3c1fc92012-11-15 00:56:46502 // The device should be unmounted by now.
503 EXPECT_FALSE(HasMountPoint("/device/mount_path"));
504
[email protected]a0278d52014-05-06 03:36:15505 // Send failing FORMAT_COMPLETED signal.
[email protected]e3c1fc92012-11-15 00:56:46506 // The failure is marked by ! in fromt of the path (but this should change
507 // soon).
[email protected]a0278d52014-05-06 03:36:15508 fake_cros_disks_client_->SendFormatCompletedEvent(
509 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path");
[email protected]e3c1fc92012-11-15 00:56:46510}
511
[email protected]e3c1fc92012-11-15 00:56:46512// Tests the case when formatting completes successfully.
513TEST_F(DiskMountManagerTest, Format_FormatSuccess) {
514 // Set up cros disks client mocks.
[email protected]f026c0f2014-05-06 21:52:35515 // Both unmount and format device cals are successful in this test.
[email protected]e3c1fc92012-11-15 00:56:46516
kjellanderdae37c42016-09-13 11:10:44517 // Set up expectations for observer mock.
518 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
519 // events (all of them without an error set).
520 {
521 InSequence s;
522
523 EXPECT_CALL(observer_,
524 OnMountEvent(DiskMountManager::UNMOUNTING,
525 chromeos::MOUNT_ERROR_NONE,
526 Field(&DiskMountManager::MountPointInfo::mount_path,
527 "/device/mount_path")))
528 .Times(1);
529
530 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
531 chromeos::FORMAT_ERROR_NONE,
532 "/device/source_path"))
533 .Times(1);
534
535 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
536 chromeos::FORMAT_ERROR_NONE,
537 "/device/source_path"))
538 .Times(1);
539 }
540
[email protected]e3c1fc92012-11-15 00:56:46541 // Start the test.
542 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
543
[email protected]f026c0f2014-05-06 21:52:35544 // Wait for Unmount and Format calls to end.
[email protected]e3c1fc92012-11-15 00:56:46545 message_loop_.RunUntilIdle();
546
[email protected]cc70f5012013-05-14 04:58:56547 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
548 EXPECT_EQ("/device/mount_path",
549 fake_cros_disks_client_->last_unmount_device_path());
550 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
551 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35552 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56553 EXPECT_EQ("/device/source_path",
[email protected]f026c0f2014-05-06 21:52:35554 fake_cros_disks_client_->last_format_device_path());
555 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56556
[email protected]e3c1fc92012-11-15 00:56:46557 // The device should be unmounted by now.
558 EXPECT_FALSE(HasMountPoint("/device/mount_path"));
559
560 // Simulate cros_disks reporting success.
[email protected]a0278d52014-05-06 03:36:15561 fake_cros_disks_client_->SendFormatCompletedEvent(
562 chromeos::FORMAT_ERROR_NONE, "/device/source_path");
[email protected]e3c1fc92012-11-15 00:56:46563}
564
565// Tests that it's possible to format the device twice in a row (this may not be
566// true if the list of pending formats is not properly cleared).
567TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) {
[email protected]f026c0f2014-05-06 21:52:35568 // All unmount and format device cals are successful in this test.
[email protected]e3c1fc92012-11-15 00:56:46569 // Each of the should be made twice (once for each formatting task).
[email protected]e3c1fc92012-11-15 00:56:46570
kjellanderdae37c42016-09-13 11:10:44571 // Set up expectations for observer mock.
572 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
573 // events (all of them without an error set) twice (once for each formatting
574 // task).
575 // Also, there should be a MOUNTING event when the device remounting is
576 // simulated.
577 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
578 chromeos::FORMAT_ERROR_NONE,
579 "/device/source_path"))
580 .Times(2);
581
582 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
583 chromeos::FORMAT_ERROR_NONE,
584 "/device/source_path"))
585 .Times(2);
586
587 EXPECT_CALL(observer_,
588 OnMountEvent(DiskMountManager::UNMOUNTING,
589 chromeos::MOUNT_ERROR_NONE,
590 Field(&DiskMountManager::MountPointInfo::mount_path,
591 "/device/mount_path")))
592 .Times(2);
593
594 EXPECT_CALL(observer_,
595 OnMountEvent(DiskMountManager::MOUNTING,
596 chromeos::MOUNT_ERROR_NONE,
597 Field(&DiskMountManager::MountPointInfo::mount_path,
598 "/device/mount_path")))
599 .Times(1);
600
[email protected]e3c1fc92012-11-15 00:56:46601 // Start the test.
602 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
603
[email protected]f026c0f2014-05-06 21:52:35604 // Wait for Unmount and Format calls to end.
[email protected]e3c1fc92012-11-15 00:56:46605 message_loop_.RunUntilIdle();
606
[email protected]cc70f5012013-05-14 04:58:56607 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
608 EXPECT_EQ("/device/mount_path",
609 fake_cros_disks_client_->last_unmount_device_path());
610 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
611 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35612 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56613 EXPECT_EQ("/device/source_path",
[email protected]f026c0f2014-05-06 21:52:35614 fake_cros_disks_client_->last_format_device_path());
615 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56616
[email protected]e3c1fc92012-11-15 00:56:46617 // The device should be unmounted by now.
618 EXPECT_FALSE(HasMountPoint("/device/mount_path"));
619
620 // Simulate cros_disks reporting success.
[email protected]a0278d52014-05-06 03:36:15621 fake_cros_disks_client_->SendFormatCompletedEvent(
622 chromeos::FORMAT_ERROR_NONE, "/device/source_path");
[email protected]e3c1fc92012-11-15 00:56:46623
624 // Simulate the device remounting.
[email protected]cc70f5012013-05-14 04:58:56625 fake_cros_disks_client_->SendMountCompletedEvent(
[email protected]e3c1fc92012-11-15 00:56:46626 chromeos::MOUNT_ERROR_NONE,
627 "/device/source_path",
628 chromeos::MOUNT_TYPE_DEVICE,
629 "/device/mount_path");
630
631 EXPECT_TRUE(HasMountPoint("/device/mount_path"));
632
633 // Try formatting again.
634 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
635
[email protected]f026c0f2014-05-06 21:52:35636 // Wait for Unmount and Format calls to end.
[email protected]e3c1fc92012-11-15 00:56:46637 message_loop_.RunUntilIdle();
638
[email protected]cc70f5012013-05-14 04:58:56639 EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
640 EXPECT_EQ("/device/mount_path",
641 fake_cros_disks_client_->last_unmount_device_path());
642 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
643 fake_cros_disks_client_->last_unmount_options());
[email protected]f026c0f2014-05-06 21:52:35644 EXPECT_EQ(2, fake_cros_disks_client_->format_call_count());
[email protected]cc70f5012013-05-14 04:58:56645 EXPECT_EQ("/device/source_path",
[email protected]f026c0f2014-05-06 21:52:35646 fake_cros_disks_client_->last_format_device_path());
647 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
[email protected]cc70f5012013-05-14 04:58:56648
[email protected]e3c1fc92012-11-15 00:56:46649 // Simulate cros_disks reporting success.
[email protected]a0278d52014-05-06 03:36:15650 fake_cros_disks_client_->SendFormatCompletedEvent(
651 chromeos::FORMAT_ERROR_NONE, "/device/source_path");
[email protected]e3c1fc92012-11-15 00:56:46652}
653
yamaguchi6594bf7e12016-08-24 22:16:11654TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) {
655 DiskMountManager* manager = DiskMountManager::GetInstance();
656 const std::string kSourcePath1 = "/device/source_path";
657 const std::string kSourcePath2 = "/device/source_path2";
658 const std::string kSourceFormat = std::string();
659 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE
660 // For MountCompleted. Must be non-empty strings.
661 const std::string kMountPath1 = "/media/foo";
662 const std::string kMountPath2 = "/media/bar";
663
kjellanderdae37c42016-09-13 11:10:44664 // Event handlers of observers should be called.
665 EXPECT_CALL(
666 observer_,
667 OnMountEvent(
668 DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
669 Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1)));
670 // For the 2nd source, the disk (block device) is not read-only but the
671 // test will mount it in read-only mode.
672 // Observers query |disks_| from |DiskMountManager| in its event handler for
673 // a mount completion event. Therefore |disks_| must be updated with correct
674 // |read_only| value before notifying to observers.
675 EXPECT_CALL(
676 observer_,
677 OnMountEvent(
678 DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
679 Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath2)))
680 .WillOnce(InvokeWithoutArgs(
681 // Verify if the disk appears read-only at the time of notification
682 // to observers.
683 [&]() { ExpectDiskReadOnly(manager, kSourcePath2, true); }));
684
yamaguchi6594bf7e12016-08-24 22:16:11685 manager->MountPath(kSourcePath1, kSourceFormat, std::string(),
686 chromeos::MOUNT_TYPE_DEVICE,
687 chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
688 manager->MountPath(kSourcePath2, kSourceFormat, std::string(),
689 chromeos::MOUNT_TYPE_DEVICE,
690 chromeos::MOUNT_ACCESS_MODE_READ_ONLY);
691 // Simulate cros_disks reporting mount completed.
692 fake_cros_disks_client_->SendMountCompletedEvent(
693 chromeos::MOUNT_ERROR_NONE, kSourcePath1, chromeos::MOUNT_TYPE_DEVICE,
694 kMountPath1);
695 fake_cros_disks_client_->SendMountCompletedEvent(
696 chromeos::MOUNT_ERROR_NONE, kSourcePath2, chromeos::MOUNT_TYPE_DEVICE,
697 kMountPath2);
698
699 const DiskMountManager::DiskMap& disks = manager->disks();
700 ASSERT_GT(disks.count(kSourcePath1), 0U);
701 EXPECT_FALSE(disks.find(kSourcePath1)->second->is_read_only());
702 ASSERT_GT(disks.count(kSourcePath2), 0U);
703 EXPECT_TRUE(disks.find(kSourcePath2)->second->is_read_only());
704}
705
yamaguchi21448d5b2016-09-06 02:04:56706TEST_F(DiskMountManagerTest, MountPath_ReadOnlyDevice) {
707 DiskMountManager* manager = DiskMountManager::GetInstance();
708 const std::string kSourceFormat = std::string();
709 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE
710
kjellanderdae37c42016-09-13 11:10:44711 // Event handlers of observers should be called.
712 EXPECT_CALL(
713 observer_,
714 OnMountEvent(DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
715 Field(&DiskMountManager::MountPointInfo::mount_path,
716 kReadOnlyMountpath)));
717
yamaguchi21448d5b2016-09-06 02:04:56718 // Attempt to mount a read-only device in read-write mode.
719 manager->MountPath(kReadOnlyDeviceSource, kSourceFormat, std::string(),
720 chromeos::MOUNT_TYPE_DEVICE,
721 chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
722 // Simulate cros_disks reporting mount completed.
723 fake_cros_disks_client_->SendMountCompletedEvent(
724 chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceSource,
725 chromeos::MOUNT_TYPE_DEVICE, kReadOnlyMountpath);
726
727 const DiskMountManager::DiskMap& disks = manager->disks();
728 ASSERT_GT(disks.count(kReadOnlyDeviceSource), 0U);
729 // The mounted disk should preserve the read-only flag of the block device.
730 EXPECT_TRUE(disks.find(kReadOnlyDeviceSource)->second->is_read_only());
731}
732
[email protected]e3c1fc92012-11-15 00:56:46733} // namespace