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