Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/memory/ptr_util.h" | |
| 9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/strings/stringprintf.h" | |
| 11 #include "chromeos/dbus/dbus_thread_manager.h" | 13 #include "chromeos/dbus/dbus_thread_manager.h" |
| 12 #include "chromeos/dbus/fake_cros_disks_client.h" | 14 #include "chromeos/dbus/fake_cros_disks_client.h" |
| 13 #include "chromeos/disks/disk_mount_manager.h" | 15 #include "chromeos/disks/disk_mount_manager.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 17 |
| 18 using base::MakeUnique; | |
| 19 using base::StringPrintf; | |
| 17 using chromeos::disks::DiskMountManager; | 20 using chromeos::disks::DiskMountManager; |
| 18 using chromeos::CrosDisksClient; | 21 using chromeos::CrosDisksClient; |
| 19 using chromeos::DBusThreadManager; | 22 using chromeos::DBusThreadManager; |
| 20 using chromeos::FakeCrosDisksClient; | 23 using chromeos::FakeCrosDisksClient; |
| 21 using testing::_; | 24 using chromeos::MountType; |
| 22 using testing::Field; | 25 using chromeos::disks::MountCondition; |
| 23 using testing::InSequence; | |
| 24 using testing::InvokeWithoutArgs; | |
| 25 | 26 |
| 26 namespace { | 27 namespace { |
| 27 | 28 |
| 28 const char kReadOnlyMountpath[] = "/device/read_only_mount_path"; | 29 const char kReadOnlyMountpath[] = "/device/read_only_mount_path"; |
| 29 const char kReadOnlyDeviceSource[] = "/device/read_only_source_path"; | 30 const char kReadOnlyDeviceSource[] = "/device/read_only_source_path"; |
| 30 | 31 |
| 31 // Holds information needed to create a DiskMountManager::Disk instance. | 32 // Holds information needed to create a DiskMountManager::Disk instance. |
| 32 struct TestDiskInfo { | 33 struct TestDiskInfo { |
| 33 const char* source_path; | 34 const char* source_path; |
| 34 const char* mount_path; | 35 const char* mount_path; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 chromeos::disks::MOUNT_CONDITION_NONE | 146 chromeos::disks::MOUNT_CONDITION_NONE |
| 146 }, | 147 }, |
| 147 { | 148 { |
| 148 kReadOnlyDeviceSource, | 149 kReadOnlyDeviceSource, |
| 149 kReadOnlyMountpath, | 150 kReadOnlyMountpath, |
| 150 chromeos::MOUNT_TYPE_DEVICE, | 151 chromeos::MOUNT_TYPE_DEVICE, |
| 151 chromeos::disks::MOUNT_CONDITION_NONE | 152 chromeos::disks::MOUNT_CONDITION_NONE |
| 152 }, | 153 }, |
| 153 }; | 154 }; |
| 154 | 155 |
| 155 // Mocks DiskMountManager observer. | 156 // Represents which function in |DiskMountManager::Observer| was invoked. |
| 157 enum ObserverEventType { | |
| 158 DEVICE_EVENT, // OnDeviceEvent() | |
| 159 DISK_EVENT, // OnDiskEvent() | |
| 160 FORMAT_EVENT, // OnFormatEvent() | |
| 161 MOUNT_EVENT // OnMountEvent() | |
| 162 }; | |
| 163 | |
| 164 // Represents every event notified to |DiskMountManager::Observer|. | |
| 165 struct ObserverEvent { | |
|
fukino
2016/09/15 03:15:00
Virtual destructor should be required in this base
| |
| 166 public: | |
| 167 virtual ObserverEventType type() const = 0; | |
| 168 }; | |
| 169 | |
| 170 // Represents an invocation of |DiskMountManager::Observer::OnDeviceEvent()|. | |
| 171 struct DeviceEvent : public ObserverEvent { | |
| 172 DiskMountManager::DeviceEvent event; | |
| 173 std::string device_path; | |
| 174 | |
| 175 DeviceEvent() {} | |
| 176 | |
| 177 DeviceEvent(DiskMountManager::DeviceEvent event, | |
| 178 const std::string& device_path) | |
| 179 : event(event), device_path(device_path) {} | |
| 180 | |
| 181 ObserverEventType type() const override { return DEVICE_EVENT; } | |
| 182 | |
| 183 bool operator==(const DeviceEvent& other) const { | |
| 184 return event == other.event && device_path == other.device_path; | |
| 185 } | |
| 186 | |
| 187 std::string DebugString() const { | |
| 188 return StringPrintf("OnDeviceEvent(%d, %s)", event, device_path.c_str()); | |
| 189 } | |
| 190 }; | |
| 191 | |
| 192 // Represents an invocation of |DiskMountManager::Observer::OnDiskEvent()|. | |
| 193 struct DiskEvent : public ObserverEvent { | |
| 194 DiskMountManager::DiskEvent event; | |
| 195 std::unique_ptr<DiskMountManager::Disk> disk; | |
| 196 | |
| 197 DiskEvent(DiskMountManager::DiskEvent event, | |
| 198 const DiskMountManager::Disk& disk) | |
| 199 : event(event), | |
| 200 disk(std::unique_ptr<DiskMountManager::Disk>( | |
| 201 new DiskMountManager::Disk(disk))) {} | |
| 202 | |
| 203 DiskEvent(DiskEvent&& other) | |
| 204 : event(other.event), disk(std::move(other.disk)) {} | |
| 205 | |
| 206 ObserverEventType type() const override { return DISK_EVENT; } | |
| 207 | |
| 208 bool operator==(const DiskEvent& other) const { | |
| 209 return event == other.event && disk == other.disk; | |
| 210 } | |
| 211 | |
| 212 std::string DebugString() const { | |
| 213 return StringPrintf("OnDiskEvent(event=%d, device_path=%s, mount_path=%s", | |
| 214 event, disk->device_path().c_str(), | |
| 215 disk->mount_path().c_str()); | |
| 216 } | |
| 217 }; | |
| 218 | |
| 219 // Represents an invocation of |DiskMountManager::Observer::OnFormatEvent()|. | |
| 220 struct FormatEvent : public ObserverEvent { | |
| 221 DiskMountManager::FormatEvent event; | |
| 222 chromeos::FormatError error_code; | |
| 223 std::string device_path; | |
| 224 | |
| 225 FormatEvent() {} | |
| 226 FormatEvent(DiskMountManager::FormatEvent event, | |
| 227 chromeos::FormatError error_code, | |
| 228 const std::string& device_path) | |
| 229 : event(event), error_code(error_code), device_path(device_path) {} | |
| 230 | |
| 231 ObserverEventType type() const override { return FORMAT_EVENT; } | |
| 232 | |
| 233 bool operator==(const FormatEvent& other) const { | |
| 234 return event == other.event && error_code == other.error_code && | |
| 235 device_path == other.device_path; | |
| 236 } | |
| 237 | |
| 238 std::string DebugString() const { | |
| 239 return StringPrintf("OnFormatEvent(%d, %d, %s)", event, error_code, | |
| 240 device_path.c_str()); | |
| 241 } | |
| 242 }; | |
| 243 | |
| 244 // Represents an invocation of |DiskMountManager::Observer::OnMountEvent()|. | |
| 245 struct MountEvent : public ObserverEvent { | |
| 246 DiskMountManager::MountEvent event; | |
| 247 chromeos::MountError error_code; | |
| 248 DiskMountManager::MountPointInfo mount_point; | |
| 249 | |
| 250 // Not passed to callback, but read by handlers. So it's captured upon | |
| 251 // callback. | |
| 252 std::unique_ptr<DiskMountManager::Disk> disk; | |
| 253 | |
| 254 MountEvent(MountEvent&& other) | |
| 255 : event(other.event), | |
| 256 error_code(other.error_code), | |
| 257 mount_point(other.mount_point), | |
| 258 disk(std::move(other.disk)) {} | |
| 259 MountEvent(DiskMountManager::MountEvent event, | |
| 260 chromeos::MountError error_code, | |
| 261 const DiskMountManager::MountPointInfo& mount_point, | |
| 262 const DiskMountManager::Disk& disk) | |
| 263 : event(event), | |
| 264 error_code(error_code), | |
| 265 mount_point(mount_point), | |
| 266 disk(new DiskMountManager::Disk(disk)) {} | |
| 267 | |
| 268 ObserverEventType type() const override { return MOUNT_EVENT; } | |
| 269 | |
| 270 bool operator==(const MountEvent& other) const; | |
| 271 | |
| 272 std::string DebugString() const { | |
| 273 return StringPrintf("OnMountEvent(%d, %d, %s, %s, %d, %d)", event, | |
| 274 error_code, mount_point.source_path.c_str(), | |
| 275 mount_point.mount_path.c_str(), mount_point.mount_type, | |
| 276 mount_point.mount_condition); | |
| 277 } | |
| 278 }; | |
| 279 | |
| 280 // A mock |Observer| class which records all invocation of the methods invoked | |
| 281 // from DiskMountManager and all the arguments passed to them. | |
| 156 class MockDiskMountManagerObserver : public DiskMountManager::Observer { | 282 class MockDiskMountManagerObserver : public DiskMountManager::Observer { |
| 157 public: | 283 public: |
| 158 virtual ~MockDiskMountManagerObserver() {} | 284 MockDiskMountManagerObserver(const DiskMountManager* manager) |
| 159 | 285 : manager_(manager) {} |
| 160 MOCK_METHOD2(OnDiskEvent, void(DiskMountManager::DiskEvent event, | 286 ~MockDiskMountManagerObserver() override {} |
| 161 const DiskMountManager::Disk* disk)); | 287 |
| 162 MOCK_METHOD2(OnDeviceEvent, void(DiskMountManager::DeviceEvent event, | 288 // Mock notify methods. |
| 163 const std::string& device_path)); | 289 void OnDeviceEvent(DiskMountManager::DeviceEvent event, |
| 164 MOCK_METHOD3(OnMountEvent, | 290 const std::string& device_path) override { |
| 165 void(DiskMountManager::MountEvent event, | 291 events_.push_back(MakeUnique<DeviceEvent>(event, device_path)); |
| 166 chromeos::MountError error_code, | 292 } |
| 167 const DiskMountManager::MountPointInfo& mount_point)); | 293 |
| 168 MOCK_METHOD3(OnFormatEvent, | 294 void OnDiskEvent(DiskMountManager::DiskEvent event, |
| 169 void(DiskMountManager::FormatEvent event, | 295 const DiskMountManager::Disk* disk) override { |
| 170 chromeos::FormatError error_code, | 296 // Take a snapshot (copy) of the Disk object at the time of invocation for |
| 171 const std::string& device_path)); | 297 // later verification. |
| 172 }; | 298 events_.push_back(MakeUnique<DiskEvent>(event, *disk)); |
| 173 | 299 } |
| 174 // Expect |is_read_only| value of a disk object keyed by |source_path|. | 300 |
| 175 void ExpectDiskReadOnly(const DiskMountManager* manager, | 301 void OnFormatEvent(DiskMountManager::FormatEvent event, |
| 176 const std::string& source_path, | 302 chromeos::FormatError error_code, |
| 177 bool expected) { | 303 const std::string& device_path) override { |
| 178 EXPECT_EQ(expected, | 304 events_.push_back(MakeUnique<FormatEvent>(event, error_code, device_path)); |
| 179 manager->disks().find(source_path)->second->is_read_only()); | 305 } |
| 306 | |
| 307 void OnMountEvent( | |
| 308 DiskMountManager::MountEvent event, | |
| 309 chromeos::MountError error_code, | |
| 310 const DiskMountManager::MountPointInfo& mount_point) override { | |
| 311 // Take a snapshot (copy) of a Disk object at the time of invocation. | |
| 312 // It can be verified later besides the arguments. | |
| 313 events_.push_back(MakeUnique<MountEvent>( | |
| 314 event, error_code, mount_point, | |
| 315 *manager_->disks().find(mount_point.source_path)->second)); | |
| 316 } | |
| 317 | |
| 318 // Gets invocation history to be verified by testcases. | |
| 319 // Verifies if the |index|th invocation is OnDeviceEvent() and returns | |
| 320 // details. | |
| 321 const DeviceEvent& GetDeviceEvent(size_t index) { | |
| 322 DCHECK_GT(events_.size(), index); | |
| 323 DCHECK_EQ(DEVICE_EVENT, events_[index]->type()); | |
| 324 return static_cast<const DeviceEvent&>(*events_[index]); | |
| 325 } | |
| 326 | |
| 327 // Verifies if the |index|th invocation is OnDiskEvent() and returns details. | |
| 328 const DiskEvent& GetDiskEvent(size_t index) { | |
| 329 DCHECK_GT(events_.size(), index); | |
| 330 DCHECK_EQ(DISK_EVENT, events_[index]->type()); | |
| 331 return static_cast<const DiskEvent&>(*events_[index]); | |
| 332 } | |
| 333 | |
| 334 // Verifies if the |index|th invocation is OnFormatEvent() and returns | |
| 335 // details. | |
| 336 const FormatEvent& GetFormatEvent(size_t index) { | |
| 337 DCHECK_GT(events_.size(), index); | |
| 338 DCHECK_EQ(FORMAT_EVENT, events_[index]->type()); | |
| 339 return static_cast<const FormatEvent&>(*events_[index]); | |
| 340 } | |
| 341 | |
| 342 // Verifies if the |index|th invocation is OnMountEvent() and returns details. | |
| 343 const MountEvent& GetMountEvent(size_t index) { | |
| 344 DCHECK_GT(events_.size(), index); | |
| 345 DCHECK_EQ(MOUNT_EVENT, events_[index]->type()); | |
| 346 return static_cast<const MountEvent&>(*events_[index]); | |
| 347 } | |
| 348 | |
| 349 // Returns number of callback invocations happened so far. | |
| 350 size_t GetEventCount() { return events_.size(); } | |
| 351 | |
| 352 // Counts the number of |MountEvent| recorded so far that matches the given | |
| 353 // condition. | |
| 354 size_t CountMountEvents(DiskMountManager::MountEvent mount_event_type, | |
| 355 chromeos::MountError error_code, | |
| 356 const std::string& mount_path) { | |
| 357 size_t num_matched = 0; | |
| 358 for (const auto& it : events_) { | |
| 359 if (it->type() != MOUNT_EVENT) | |
| 360 continue; | |
| 361 const MountEvent& mount_event = static_cast<const MountEvent&>(*it); | |
| 362 if (mount_event.event == mount_event_type && | |
| 363 mount_event.error_code == error_code && | |
| 364 mount_event.mount_point.mount_path == mount_path) | |
| 365 num_matched++; | |
| 366 } | |
| 367 return num_matched; | |
| 368 } | |
| 369 | |
| 370 // Counts the number of |FormatEvent| recorded so far that matches with | |
| 371 // |format_event|. | |
| 372 size_t CountFormatEvents(const FormatEvent& exptected_format_event) { | |
| 373 size_t num_matched = 0; | |
| 374 for (const auto& it : events_) { | |
| 375 if (it->type() != FORMAT_EVENT) | |
| 376 continue; | |
| 377 if (static_cast<const FormatEvent&>(*it) == exptected_format_event) | |
| 378 num_matched++; | |
| 379 } | |
| 380 return num_matched; | |
| 381 } | |
| 382 | |
| 383 private: | |
| 384 // Pointer to the manager object to which this |Observer| is registered. | |
| 385 const DiskMountManager* manager_; | |
| 386 | |
| 387 // Records all invocations. | |
| 388 std::vector<std::unique_ptr<ObserverEvent>> events_; | |
| 389 }; | |
| 390 | |
| 391 // Shift operators of ostream. | |
| 392 // Needed to print values in case of EXPECT_* failure in gtest. | |
| 393 std::ostream& operator<<(std::ostream& stream, | |
| 394 const DeviceEvent& device_event) { | |
| 395 return stream << device_event.DebugString(); | |
| 396 } | |
| 397 | |
| 398 std::ostream& operator<<(std::ostream& stream, const DiskEvent& disk_event) { | |
| 399 return stream << disk_event.DebugString(); | |
| 400 } | |
| 401 | |
| 402 std::ostream& operator<<(std::ostream& stream, | |
| 403 const FormatEvent& format_event) { | |
| 404 return stream << format_event.DebugString(); | |
| 405 } | |
| 406 | |
| 407 std::ostream& operator<<(std::ostream& stream, const MountEvent& mount_event) { | |
| 408 return stream << mount_event.DebugString(); | |
| 180 } | 409 } |
| 181 | 410 |
| 182 class DiskMountManagerTest : public testing::Test { | 411 class DiskMountManagerTest : public testing::Test { |
| 183 public: | 412 public: |
| 184 DiskMountManagerTest() {} | 413 DiskMountManagerTest() {} |
| 185 ~DiskMountManagerTest() override {} | 414 ~DiskMountManagerTest() override {} |
| 186 | 415 |
| 187 // Sets up test dbus tread manager and disks mount manager. | 416 // Sets up test dbus tread manager and disks mount manager. |
| 188 // Initializes disk mount manager disks and mount points. | 417 // Initializes disk mount manager disks and mount points. |
| 189 // Adds a test observer to the disk mount manager. | 418 // Adds a test observer to the disk mount manager. |
| 190 void SetUp() override { | 419 void SetUp() override { |
| 191 fake_cros_disks_client_ = new FakeCrosDisksClient; | 420 fake_cros_disks_client_ = new FakeCrosDisksClient; |
| 192 DBusThreadManager::GetSetterForTesting()->SetCrosDisksClient( | 421 DBusThreadManager::GetSetterForTesting()->SetCrosDisksClient( |
| 193 std::unique_ptr<CrosDisksClient>(fake_cros_disks_client_)); | 422 std::unique_ptr<CrosDisksClient>(fake_cros_disks_client_)); |
| 194 | 423 |
| 195 DiskMountManager::Initialize(); | 424 DiskMountManager::Initialize(); |
| 196 | 425 |
| 197 InitDisksAndMountPoints(); | 426 InitDisksAndMountPoints(); |
| 198 | 427 |
| 199 DiskMountManager::GetInstance()->AddObserver(&observer_); | 428 observer_.reset( |
| 429 new MockDiskMountManagerObserver(DiskMountManager::GetInstance())); | |
| 430 DiskMountManager::GetInstance()->AddObserver(observer_.get()); | |
| 200 } | 431 } |
| 201 | 432 |
| 202 // Shuts down dbus thread manager and disk moutn manager used in the test. | 433 // Shuts down dbus thread manager and disk moutn manager used in the test. |
| 203 void TearDown() override { | 434 void TearDown() override { |
| 204 DiskMountManager::GetInstance()->RemoveObserver(&observer_); | 435 DiskMountManager::GetInstance()->RemoveObserver(observer_.get()); |
| 205 DiskMountManager::Shutdown(); | 436 DiskMountManager::Shutdown(); |
| 206 DBusThreadManager::Shutdown(); | 437 DBusThreadManager::Shutdown(); |
| 207 } | 438 } |
| 208 | 439 |
| 209 protected: | 440 protected: |
| 210 // Checks if disk mount manager contains a mount point with specified moutn | 441 // Checks if disk mount manager contains a mount point with specified moutn |
| 211 // path. | 442 // path. |
| 212 bool HasMountPoint(const std::string& mount_path) { | 443 bool HasMountPoint(const std::string& mount_path) { |
| 213 const DiskMountManager::MountPointMap& mount_points = | 444 const DiskMountManager::MountPointMap& mount_points = |
| 214 DiskMountManager::GetInstance()->mount_points(); | 445 DiskMountManager::GetInstance()->mount_points(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 // expected that the corresponding disk is already added). | 489 // expected that the corresponding disk is already added). |
| 259 for (size_t i = 0; i < arraysize(kTestDisks); i++) | 490 for (size_t i = 0; i < arraysize(kTestDisks); i++) |
| 260 AddTestDisk(kTestDisks[i]); | 491 AddTestDisk(kTestDisks[i]); |
| 261 | 492 |
| 262 for (size_t i = 0; i < arraysize(kTestMountPoints); i++) | 493 for (size_t i = 0; i < arraysize(kTestMountPoints); i++) |
| 263 AddTestMountPoint(kTestMountPoints[i]); | 494 AddTestMountPoint(kTestMountPoints[i]); |
| 264 } | 495 } |
| 265 | 496 |
| 266 protected: | 497 protected: |
| 267 chromeos::FakeCrosDisksClient* fake_cros_disks_client_; | 498 chromeos::FakeCrosDisksClient* fake_cros_disks_client_; |
| 268 MockDiskMountManagerObserver observer_; | 499 std::unique_ptr<MockDiskMountManagerObserver> observer_; |
| 269 base::MessageLoopForUI message_loop_; | 500 base::MessageLoopForUI message_loop_; |
| 270 }; | 501 }; |
| 271 | 502 |
| 272 // Tests that the observer gets notified on attempt to format non existent mount | 503 // Tests that the observer gets notified on attempt to format non existent mount |
| 273 // point. | 504 // point. |
| 274 TEST_F(DiskMountManagerTest, Format_NotMounted) { | 505 TEST_F(DiskMountManagerTest, Format_NotMounted) { |
| 275 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 276 chromeos::FORMAT_ERROR_UNKNOWN, | |
| 277 "/mount/non_existent")) | |
| 278 .Times(1); | |
| 279 DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent"); | 506 DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent"); |
| 507 ASSERT_EQ(1U, observer_->GetEventCount()); | |
| 508 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 509 chromeos::FORMAT_ERROR_UNKNOWN, "/mount/non_existent"), | |
| 510 observer_->GetFormatEvent(0)); | |
| 280 } | 511 } |
| 281 | 512 |
| 282 // Tests that the observer gets notified on attempt to format read-only mount | 513 // Tests that the observer gets notified on attempt to format read-only mount |
| 283 // point. | 514 // point. |
| 284 TEST_F(DiskMountManagerTest, Format_ReadOnly) { | 515 TEST_F(DiskMountManagerTest, Format_ReadOnly) { |
| 285 EXPECT_CALL(observer_, | |
| 286 OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 287 chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED, | |
| 288 kReadOnlyMountpath)) | |
| 289 .Times(1); | |
| 290 DiskMountManager::GetInstance()->FormatMountedDevice(kReadOnlyMountpath); | 516 DiskMountManager::GetInstance()->FormatMountedDevice(kReadOnlyMountpath); |
| 517 ASSERT_EQ(1U, observer_->GetEventCount()); | |
| 518 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 519 chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED, | |
| 520 kReadOnlyMountpath), | |
| 521 observer_->GetFormatEvent(0)); | |
| 291 } | 522 } |
| 292 | 523 |
| 293 // Tests that it is not possible to format archive mount point. | 524 // Tests that it is not possible to format archive mount point. |
| 294 TEST_F(DiskMountManagerTest, Format_Archive) { | 525 TEST_F(DiskMountManagerTest, Format_Archive) { |
| 295 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 296 chromeos::FORMAT_ERROR_UNKNOWN, | |
| 297 "/archive/source_path")) | |
| 298 .Times(1); | |
| 299 | |
| 300 DiskMountManager::GetInstance()->FormatMountedDevice("/archive/mount_path"); | 526 DiskMountManager::GetInstance()->FormatMountedDevice("/archive/mount_path"); |
| 527 ASSERT_EQ(1U, observer_->GetEventCount()); | |
| 528 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 529 chromeos::FORMAT_ERROR_UNKNOWN, "/archive/source_path"), | |
| 530 observer_->GetFormatEvent(0)); | |
| 301 } | 531 } |
| 302 | 532 |
| 303 // Tests that format fails if the device cannot be unmounted. | 533 // Tests that format fails if the device cannot be unmounted. |
| 304 TEST_F(DiskMountManagerTest, Format_FailToUnmount) { | 534 TEST_F(DiskMountManagerTest, Format_FailToUnmount) { |
| 305 // Before formatting mounted device, the device should be unmounted. | 535 // Before formatting mounted device, the device should be unmounted. |
| 306 // In this test unmount will fail, and there should be no attempt to | 536 // In this test unmount will fail, and there should be no attempt to |
| 307 // format the device. | 537 // format the device. |
| 308 | 538 |
| 309 // Set up expectations for observer mock. | |
| 310 // Observer should be notified that unmount attempt fails and format task | |
| 311 // failed to start. | |
| 312 { | |
| 313 InSequence s; | |
| 314 | |
| 315 EXPECT_CALL(observer_, | |
| 316 OnMountEvent(DiskMountManager::UNMOUNTING, | |
| 317 chromeos::MOUNT_ERROR_INTERNAL, | |
| 318 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 319 "/device/mount_path"))) | |
| 320 .Times(1); | |
| 321 | |
| 322 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 323 chromeos::FORMAT_ERROR_UNKNOWN, | |
| 324 "/device/source_path")) | |
| 325 .Times(1); | |
| 326 } | |
| 327 | |
| 328 fake_cros_disks_client_->MakeUnmountFail(); | 539 fake_cros_disks_client_->MakeUnmountFail(); |
| 329 // Start test. | 540 // Start test. |
| 330 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | 541 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); |
| 331 | 542 |
| 332 // Cros disks will respond asynchronoulsy, so let's drain the message loop. | 543 // Cros disks will respond asynchronoulsy, so let's drain the message loop. |
| 333 base::RunLoop().RunUntilIdle(); | 544 base::RunLoop().RunUntilIdle(); |
| 334 | 545 |
| 546 // Observer should be notified that unmount attempt fails and format task | |
| 547 // failed to start. | |
| 548 ASSERT_EQ(2U, observer_->GetEventCount()); | |
| 549 const MountEvent& mount_event = observer_->GetMountEvent(0); | |
| 550 EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event); | |
| 551 EXPECT_EQ(chromeos::MOUNT_ERROR_INTERNAL, mount_event.error_code); | |
| 552 EXPECT_EQ("/device/mount_path", mount_event.mount_point.mount_path); | |
| 553 | |
| 554 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 555 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path"), | |
| 556 observer_->GetFormatEvent(1)); | |
| 335 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); | 557 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); |
| 336 EXPECT_EQ("/device/mount_path", | 558 EXPECT_EQ("/device/mount_path", |
| 337 fake_cros_disks_client_->last_unmount_device_path()); | 559 fake_cros_disks_client_->last_unmount_device_path()); |
| 338 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 560 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| 339 fake_cros_disks_client_->last_unmount_options()); | 561 fake_cros_disks_client_->last_unmount_options()); |
| 340 EXPECT_EQ(0, fake_cros_disks_client_->format_call_count()); | 562 EXPECT_EQ(0, fake_cros_disks_client_->format_call_count()); |
| 341 | 563 |
| 342 // The device mount should still be here. | 564 // The device mount should still be here. |
| 343 EXPECT_TRUE(HasMountPoint("/device/mount_path")); | 565 EXPECT_TRUE(HasMountPoint("/device/mount_path")); |
| 344 } | 566 } |
| 345 | 567 |
| 346 // Tests that observer is notified when cros disks fails to start format | 568 // Tests that observer is notified when cros disks fails to start format |
| 347 // process. | 569 // process. |
| 348 TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) { | 570 TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) { |
| 349 // Before formatting mounted device, the device should be unmounted. | 571 // Before formatting mounted device, the device should be unmounted. |
| 350 // In this test, unmount will succeed, but call to Format method will | 572 // In this test, unmount will succeed, but call to Format method will |
| 351 // fail. | 573 // fail. |
| 352 | 574 |
| 353 // Set up expectations for observer mock. | |
| 354 // Observer should be notified that the device was unmounted and format task | |
| 355 // failed to start. | |
| 356 { | |
| 357 InSequence s; | |
| 358 | |
| 359 EXPECT_CALL(observer_, | |
| 360 OnMountEvent(DiskMountManager::UNMOUNTING, | |
| 361 chromeos::MOUNT_ERROR_NONE, | |
| 362 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 363 "/device/mount_path"))) | |
| 364 .Times(1); | |
| 365 | |
| 366 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 367 chromeos::FORMAT_ERROR_UNKNOWN, | |
| 368 "/device/source_path")) | |
| 369 .Times(1); | |
| 370 } | |
| 371 | |
| 372 fake_cros_disks_client_->MakeFormatFail(); | 575 fake_cros_disks_client_->MakeFormatFail(); |
| 373 // Start the test. | 576 // Start the test. |
| 374 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | 577 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); |
| 375 | 578 |
| 376 // Cros disks will respond asynchronoulsy, so let's drain the message loop. | 579 // Cros disks will respond asynchronoulsy, so let's drain the message loop. |
| 377 base::RunLoop().RunUntilIdle(); | 580 base::RunLoop().RunUntilIdle(); |
| 378 | 581 |
| 582 // Observer should be notified that the device was unmounted and format task | |
| 583 // failed to start. | |
| 584 ASSERT_EQ(2U, observer_->GetEventCount()); | |
| 585 const MountEvent& mount_event = observer_->GetMountEvent(0); | |
| 586 EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event); | |
| 587 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code); | |
| 588 EXPECT_EQ("/device/mount_path", mount_event.mount_point.mount_path); | |
| 589 | |
| 590 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 591 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path"), | |
| 592 observer_->GetFormatEvent(1)); | |
| 593 | |
| 379 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); | 594 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); |
| 380 EXPECT_EQ("/device/mount_path", | 595 EXPECT_EQ("/device/mount_path", |
| 381 fake_cros_disks_client_->last_unmount_device_path()); | 596 fake_cros_disks_client_->last_unmount_device_path()); |
| 382 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 597 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| 383 fake_cros_disks_client_->last_unmount_options()); | 598 fake_cros_disks_client_->last_unmount_options()); |
| 384 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); | 599 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); |
| 385 EXPECT_EQ("/device/source_path", | 600 EXPECT_EQ("/device/source_path", |
| 386 fake_cros_disks_client_->last_format_device_path()); | 601 fake_cros_disks_client_->last_format_device_path()); |
| 387 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); | 602 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); |
| 388 | 603 |
| 389 // The device mount should be gone. | 604 // The device mount should be gone. |
| 390 EXPECT_FALSE(HasMountPoint("/device/mount_path")); | 605 EXPECT_FALSE(HasMountPoint("/device/mount_path")); |
| 391 } | 606 } |
| 392 | 607 |
| 393 // Tests the case where there are two format requests for the same device. | 608 // Tests the case where there are two format requests for the same device. |
| 394 TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) { | 609 TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) { |
| 395 // Only the first format request should be processed (the second unmount | 610 // Only the first format request should be processed (the second unmount |
| 396 // request fails because the device is already unmounted at that point). | 611 // request fails because the device is already unmounted at that point). |
| 397 // CrosDisksClient will report that the format process for the first request | 612 // CrosDisksClient will report that the format process for the first request |
| 398 // is successfully started. | 613 // is successfully started. |
| 399 | 614 |
| 400 // Set up expectations for observer mock. | 615 fake_cros_disks_client_->set_unmount_listener( |
| 616 base::Bind(&FakeCrosDisksClient::MakeUnmountFail, | |
| 617 base::Unretained(fake_cros_disks_client_))); | |
| 618 // Start the test. | |
| 619 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | |
| 620 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | |
| 621 | |
| 622 // Cros disks will respond asynchronoulsy, so let's drain the message loop. | |
| 623 base::RunLoop().RunUntilIdle(); | |
| 624 | |
| 401 // The observer should get a FORMAT_STARTED event for one format request and a | 625 // The observer should get a FORMAT_STARTED event for one format request and a |
| 402 // FORMAT_COMPLETED with an error code for the other format request. The | 626 // FORMAT_COMPLETED with an error code for the other format request. The |
| 403 // formatting will be started only for the first request. | 627 // formatting will be started only for the first request. |
| 404 // There should be only one UNMOUNTING event. The result of the second one | 628 // There should be only one UNMOUNTING event. The result of the second one |
| 405 // should not be reported as the mount point will go away after the first | 629 // should not be reported as the mount point will go away after the first |
| 406 // request. | 630 // request. |
| 407 // | 631 // |
| 408 // Note that in this test the format completion signal will not be simulated, | 632 // Note that in this test the format completion signal will not be simulated, |
| 409 // so the observer should not get FORMAT_COMPLETED signal. | 633 // so the observer should not get FORMAT_COMPLETED signal. |
| 410 { | |
| 411 InSequence s; | |
| 412 | 634 |
| 413 EXPECT_CALL(observer_, | 635 ASSERT_EQ(3U, observer_->GetEventCount()); |
| 414 OnMountEvent(DiskMountManager::UNMOUNTING, | 636 const MountEvent& mount_event = observer_->GetMountEvent(0); |
| 415 chromeos::MOUNT_ERROR_NONE, | 637 EXPECT_EQ(DiskMountManager::UNMOUNTING, mount_event.event); |
| 416 Field(&DiskMountManager::MountPointInfo::mount_path, | 638 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, mount_event.error_code); |
| 417 "/device/mount_path"))) | 639 EXPECT_EQ("/device/mount_path", mount_event.mount_point.mount_path); |
| 418 .Times(1); | 640 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, |
| 419 | 641 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path"), |
| 420 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | 642 observer_->GetFormatEvent(1)); |
| 421 chromeos::FORMAT_ERROR_UNKNOWN, | 643 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED, |
| 422 "/device/source_path")) | 644 chromeos::FORMAT_ERROR_NONE, "/device/source_path"), |
| 423 .Times(1); | 645 observer_->GetFormatEvent(2)); |
| 424 | |
| 425 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED, | |
| 426 chromeos::FORMAT_ERROR_NONE, | |
| 427 "/device/source_path")) | |
| 428 .Times(1); | |
| 429 } | |
| 430 | |
| 431 fake_cros_disks_client_->set_unmount_listener( | |
| 432 base::Bind(&FakeCrosDisksClient::MakeUnmountFail, | |
| 433 base::Unretained(fake_cros_disks_client_))); | |
| 434 // Start the test. | |
| 435 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | |
| 436 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | |
| 437 | |
| 438 // Cros disks will respond asynchronoulsy, so let's drain the message loop. | |
| 439 base::RunLoop().RunUntilIdle(); | |
| 440 | 646 |
| 441 EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count()); | 647 EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count()); |
| 442 EXPECT_EQ("/device/mount_path", | 648 EXPECT_EQ("/device/mount_path", |
| 443 fake_cros_disks_client_->last_unmount_device_path()); | 649 fake_cros_disks_client_->last_unmount_device_path()); |
| 444 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 650 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| 445 fake_cros_disks_client_->last_unmount_options()); | 651 fake_cros_disks_client_->last_unmount_options()); |
| 446 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); | 652 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); |
| 447 EXPECT_EQ("/device/source_path", | 653 EXPECT_EQ("/device/source_path", |
| 448 fake_cros_disks_client_->last_format_device_path()); | 654 fake_cros_disks_client_->last_format_device_path()); |
| 449 EXPECT_EQ("vfat", | 655 EXPECT_EQ("vfat", |
| 450 fake_cros_disks_client_->last_format_filesystem()); | 656 fake_cros_disks_client_->last_format_filesystem()); |
| 451 | 657 |
| 452 // The device mount should be gone. | 658 // The device mount should be gone. |
| 453 EXPECT_FALSE(HasMountPoint("/device/mount_path")); | 659 EXPECT_FALSE(HasMountPoint("/device/mount_path")); |
| 454 } | 660 } |
| 455 | 661 |
| 662 // Verifies a |MountEvent| with the given condition. This function only checks | |
| 663 // the |mount_path| in |MountPointInfo| to make sure to match the event with | |
| 664 // preceding mount invocations. | |
| 665 void VerifyMountEvent(const MountEvent& mount_event, | |
| 666 DiskMountManager::MountEvent mount_event_type, | |
| 667 chromeos::MountError error_code, | |
| 668 const std::string& mount_path) { | |
| 669 EXPECT_EQ(mount_event_type, mount_event.event); | |
| 670 EXPECT_EQ(error_code, mount_event.error_code); | |
| 671 EXPECT_EQ(mount_path, mount_event.mount_point.mount_path); | |
| 672 } | |
| 673 | |
| 456 // Tests the case when the format process actually starts and fails. | 674 // Tests the case when the format process actually starts and fails. |
| 457 TEST_F(DiskMountManagerTest, Format_FormatFails) { | 675 TEST_F(DiskMountManagerTest, Format_FormatFails) { |
| 458 // Both unmount and format device cals are successful in this test. | 676 // Both unmount and format device cals are successful in this test. |
| 459 | 677 |
| 460 // Set up expectations for observer mock. | |
| 461 // The observer should get notified that the device was unmounted and that | |
| 462 // formatting has started. | |
| 463 // After the formatting starts, the test will simulate failing | |
| 464 // FORMAT_COMPLETED signal, so the observer should also be notified the | |
| 465 // formatting has failed (FORMAT_COMPLETED event). | |
| 466 { | |
| 467 InSequence s; | |
| 468 | |
| 469 EXPECT_CALL(observer_, | |
| 470 OnMountEvent(DiskMountManager::UNMOUNTING, | |
| 471 chromeos::MOUNT_ERROR_NONE, | |
| 472 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 473 "/device/mount_path"))) | |
| 474 .Times(1); | |
| 475 | |
| 476 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED, | |
| 477 chromeos::FORMAT_ERROR_NONE, | |
| 478 "/device/source_path")) | |
| 479 .Times(1); | |
| 480 | |
| 481 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 482 chromeos::FORMAT_ERROR_UNKNOWN, | |
| 483 "/device/source_path")) | |
| 484 .Times(1); | |
| 485 } | |
| 486 | |
| 487 // Start the test. | 678 // Start the test. |
| 488 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | 679 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); |
| 489 | 680 |
| 490 // Wait for Unmount and Format calls to end. | 681 // Wait for Unmount and Format calls to end. |
| 491 base::RunLoop().RunUntilIdle(); | 682 base::RunLoop().RunUntilIdle(); |
| 492 | 683 |
| 493 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); | 684 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); |
| 494 EXPECT_EQ("/device/mount_path", | 685 EXPECT_EQ("/device/mount_path", |
| 495 fake_cros_disks_client_->last_unmount_device_path()); | 686 fake_cros_disks_client_->last_unmount_device_path()); |
| 496 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 687 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| 497 fake_cros_disks_client_->last_unmount_options()); | 688 fake_cros_disks_client_->last_unmount_options()); |
| 498 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); | 689 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); |
| 499 EXPECT_EQ("/device/source_path", | 690 EXPECT_EQ("/device/source_path", |
| 500 fake_cros_disks_client_->last_format_device_path()); | 691 fake_cros_disks_client_->last_format_device_path()); |
| 501 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); | 692 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); |
| 502 | 693 |
| 503 // The device should be unmounted by now. | 694 // The device should be unmounted by now. |
| 504 EXPECT_FALSE(HasMountPoint("/device/mount_path")); | 695 EXPECT_FALSE(HasMountPoint("/device/mount_path")); |
| 505 | 696 |
| 506 // Send failing FORMAT_COMPLETED signal. | 697 // Send failing FORMAT_COMPLETED signal. |
| 507 // The failure is marked by ! in fromt of the path (but this should change | 698 // The failure is marked by ! in fromt of the path (but this should change |
| 508 // soon). | 699 // soon). |
| 509 fake_cros_disks_client_->SendFormatCompletedEvent( | 700 fake_cros_disks_client_->SendFormatCompletedEvent( |
| 510 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path"); | 701 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path"); |
| 702 | |
| 703 // The observer should get notified that the device was unmounted and that | |
| 704 // formatting has started. | |
| 705 // After the formatting starts, the test will simulate failing | |
| 706 // FORMAT_COMPLETED signal, so the observer should also be notified the | |
| 707 // formatting has failed (FORMAT_COMPLETED event). | |
| 708 ASSERT_EQ(3U, observer_->GetEventCount()); | |
| 709 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING, | |
| 710 chromeos::MOUNT_ERROR_NONE, "/device/mount_path"); | |
| 711 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED, | |
| 712 chromeos::FORMAT_ERROR_NONE, "/device/source_path"), | |
| 713 observer_->GetFormatEvent(1)); | |
| 714 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 715 chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path"), | |
| 716 observer_->GetFormatEvent(2)); | |
| 511 } | 717 } |
| 512 | 718 |
| 513 // Tests the case when formatting completes successfully. | 719 // Tests the case when formatting completes successfully. |
| 514 TEST_F(DiskMountManagerTest, Format_FormatSuccess) { | 720 TEST_F(DiskMountManagerTest, Format_FormatSuccess) { |
| 515 // Set up cros disks client mocks. | 721 // Set up cros disks client mocks. |
| 516 // Both unmount and format device cals are successful in this test. | 722 // Both unmount and format device cals are successful in this test. |
| 517 | 723 |
| 518 // Set up expectations for observer mock. | |
| 519 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED | |
| 520 // events (all of them without an error set). | |
| 521 { | |
| 522 InSequence s; | |
| 523 | |
| 524 EXPECT_CALL(observer_, | |
| 525 OnMountEvent(DiskMountManager::UNMOUNTING, | |
| 526 chromeos::MOUNT_ERROR_NONE, | |
| 527 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 528 "/device/mount_path"))) | |
| 529 .Times(1); | |
| 530 | |
| 531 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED, | |
| 532 chromeos::FORMAT_ERROR_NONE, | |
| 533 "/device/source_path")) | |
| 534 .Times(1); | |
| 535 | |
| 536 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 537 chromeos::FORMAT_ERROR_NONE, | |
| 538 "/device/source_path")) | |
| 539 .Times(1); | |
| 540 } | |
| 541 | |
| 542 // Start the test. | 724 // Start the test. |
| 543 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | 725 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); |
| 544 | 726 |
| 545 // Wait for Unmount and Format calls to end. | 727 // Wait for Unmount and Format calls to end. |
| 546 base::RunLoop().RunUntilIdle(); | 728 base::RunLoop().RunUntilIdle(); |
| 547 | 729 |
| 548 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); | 730 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); |
| 549 EXPECT_EQ("/device/mount_path", | 731 EXPECT_EQ("/device/mount_path", |
| 550 fake_cros_disks_client_->last_unmount_device_path()); | 732 fake_cros_disks_client_->last_unmount_device_path()); |
| 551 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 733 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| 552 fake_cros_disks_client_->last_unmount_options()); | 734 fake_cros_disks_client_->last_unmount_options()); |
| 553 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); | 735 EXPECT_EQ(1, fake_cros_disks_client_->format_call_count()); |
| 554 EXPECT_EQ("/device/source_path", | 736 EXPECT_EQ("/device/source_path", |
| 555 fake_cros_disks_client_->last_format_device_path()); | 737 fake_cros_disks_client_->last_format_device_path()); |
| 556 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); | 738 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); |
| 557 | 739 |
| 558 // The device should be unmounted by now. | 740 // The device should be unmounted by now. |
| 559 EXPECT_FALSE(HasMountPoint("/device/mount_path")); | 741 EXPECT_FALSE(HasMountPoint("/device/mount_path")); |
| 560 | 742 |
| 561 // Simulate cros_disks reporting success. | 743 // Simulate cros_disks reporting success. |
| 562 fake_cros_disks_client_->SendFormatCompletedEvent( | 744 fake_cros_disks_client_->SendFormatCompletedEvent( |
| 563 chromeos::FORMAT_ERROR_NONE, "/device/source_path"); | 745 chromeos::FORMAT_ERROR_NONE, "/device/source_path"); |
| 746 | |
| 747 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED | |
| 748 // events (all of them without an error set). | |
| 749 ASSERT_EQ(3U, observer_->GetEventCount()); | |
| 750 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::UNMOUNTING, | |
| 751 chromeos::MOUNT_ERROR_NONE, "/device/mount_path"); | |
| 752 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_STARTED, | |
| 753 chromeos::FORMAT_ERROR_NONE, "/device/source_path"), | |
| 754 observer_->GetFormatEvent(1)); | |
| 755 EXPECT_EQ(FormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 756 chromeos::FORMAT_ERROR_NONE, "/device/source_path"), | |
| 757 observer_->GetFormatEvent(2)); | |
| 564 } | 758 } |
| 565 | 759 |
| 566 // Tests that it's possible to format the device twice in a row (this may not be | 760 // Tests that it's possible to format the device twice in a row (this may not be |
| 567 // true if the list of pending formats is not properly cleared). | 761 // true if the list of pending formats is not properly cleared). |
| 568 TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) { | 762 TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) { |
| 569 // All unmount and format device cals are successful in this test. | 763 // All unmount and format device cals are successful in this test. |
| 570 // Each of the should be made twice (once for each formatting task). | 764 // Each of the should be made twice (once for each formatting task). |
| 571 | 765 |
| 572 // Set up expectations for observer mock. | |
| 573 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED | |
| 574 // events (all of them without an error set) twice (once for each formatting | |
| 575 // task). | |
| 576 // Also, there should be a MOUNTING event when the device remounting is | |
| 577 // simulated. | |
| 578 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED, | |
| 579 chromeos::FORMAT_ERROR_NONE, | |
| 580 "/device/source_path")) | |
| 581 .Times(2); | |
| 582 | |
| 583 EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED, | |
| 584 chromeos::FORMAT_ERROR_NONE, | |
| 585 "/device/source_path")) | |
| 586 .Times(2); | |
| 587 | |
| 588 EXPECT_CALL(observer_, | |
| 589 OnMountEvent(DiskMountManager::UNMOUNTING, | |
| 590 chromeos::MOUNT_ERROR_NONE, | |
| 591 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 592 "/device/mount_path"))) | |
| 593 .Times(2); | |
| 594 | |
| 595 EXPECT_CALL(observer_, | |
| 596 OnMountEvent(DiskMountManager::MOUNTING, | |
| 597 chromeos::MOUNT_ERROR_NONE, | |
| 598 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 599 "/device/mount_path"))) | |
| 600 .Times(1); | |
| 601 | |
| 602 // Start the test. | 766 // Start the test. |
| 603 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); | 767 DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path"); |
| 604 | 768 |
| 605 // Wait for Unmount and Format calls to end. | 769 // Wait for Unmount and Format calls to end. |
| 606 base::RunLoop().RunUntilIdle(); | 770 base::RunLoop().RunUntilIdle(); |
| 607 | 771 |
| 608 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); | 772 EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count()); |
| 609 EXPECT_EQ("/device/mount_path", | 773 EXPECT_EQ("/device/mount_path", |
| 610 fake_cros_disks_client_->last_unmount_device_path()); | 774 fake_cros_disks_client_->last_unmount_device_path()); |
| 611 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 775 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, | 807 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE, |
| 644 fake_cros_disks_client_->last_unmount_options()); | 808 fake_cros_disks_client_->last_unmount_options()); |
| 645 EXPECT_EQ(2, fake_cros_disks_client_->format_call_count()); | 809 EXPECT_EQ(2, fake_cros_disks_client_->format_call_count()); |
| 646 EXPECT_EQ("/device/source_path", | 810 EXPECT_EQ("/device/source_path", |
| 647 fake_cros_disks_client_->last_format_device_path()); | 811 fake_cros_disks_client_->last_format_device_path()); |
| 648 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); | 812 EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem()); |
| 649 | 813 |
| 650 // Simulate cros_disks reporting success. | 814 // Simulate cros_disks reporting success. |
| 651 fake_cros_disks_client_->SendFormatCompletedEvent( | 815 fake_cros_disks_client_->SendFormatCompletedEvent( |
| 652 chromeos::FORMAT_ERROR_NONE, "/device/source_path"); | 816 chromeos::FORMAT_ERROR_NONE, "/device/source_path"); |
| 817 | |
| 818 // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED | |
| 819 // events (all of them without an error set) twice (once for each formatting | |
| 820 // task). | |
| 821 // Also, there should be a MOUNTING event when the device remounting is | |
| 822 // simulated. | |
| 823 EXPECT_EQ(7U, observer_->GetEventCount()); | |
| 824 | |
| 825 EXPECT_EQ(2U, observer_->CountFormatEvents(FormatEvent( | |
| 826 DiskMountManager::FORMAT_COMPLETED, | |
| 827 chromeos::FORMAT_ERROR_NONE, "/device/source_path"))); | |
| 828 | |
| 829 EXPECT_EQ(2U, observer_->CountFormatEvents(FormatEvent( | |
| 830 DiskMountManager::FORMAT_STARTED, | |
| 831 chromeos::FORMAT_ERROR_NONE, "/device/source_path"))); | |
| 832 | |
| 833 EXPECT_EQ(2U, observer_->CountMountEvents(DiskMountManager::UNMOUNTING, | |
| 834 chromeos::MOUNT_ERROR_NONE, | |
| 835 "/device/mount_path")); | |
| 836 | |
| 837 EXPECT_EQ(1U, observer_->CountMountEvents(DiskMountManager::MOUNTING, | |
| 838 chromeos::MOUNT_ERROR_NONE, | |
| 839 "/device/mount_path")); | |
| 653 } | 840 } |
| 654 | 841 |
| 655 TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) { | 842 TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) { |
| 656 DiskMountManager* manager = DiskMountManager::GetInstance(); | 843 DiskMountManager* manager = DiskMountManager::GetInstance(); |
| 657 const std::string kSourcePath1 = "/device/source_path"; | 844 const std::string kSourcePath1 = "/device/source_path"; |
| 658 const std::string kSourcePath2 = "/device/source_path2"; | 845 const std::string kSourcePath2 = "/device/source_path2"; |
| 659 const std::string kSourceFormat = std::string(); | 846 const std::string kSourceFormat = std::string(); |
| 660 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE | 847 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE |
| 661 // For MountCompleted. Must be non-empty strings. | 848 // For MountCompleted. Must be non-empty strings. |
| 662 const std::string kMountPath1 = "/media/foo"; | 849 const std::string kMountPath1 = "/media/foo"; |
| 663 const std::string kMountPath2 = "/media/bar"; | 850 const std::string kMountPath2 = "/media/bar"; |
| 664 | 851 |
| 665 // Event handlers of observers should be called. | |
| 666 EXPECT_CALL( | |
| 667 observer_, | |
| 668 OnMountEvent( | |
| 669 DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE, | |
| 670 Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1))); | |
| 671 // For the 2nd source, the disk (block device) is not read-only but the | |
| 672 // test will mount it in read-only mode. | |
| 673 // Observers query |disks_| from |DiskMountManager| in its event handler for | |
| 674 // a mount completion event. Therefore |disks_| must be updated with correct | |
| 675 // |read_only| value before notifying to observers. | |
| 676 EXPECT_CALL( | |
| 677 observer_, | |
| 678 OnMountEvent( | |
| 679 DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE, | |
| 680 Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath2))) | |
| 681 .WillOnce(InvokeWithoutArgs( | |
| 682 // Verify if the disk appears read-only at the time of notification | |
| 683 // to observers. | |
| 684 [&]() { ExpectDiskReadOnly(manager, kSourcePath2, true); })); | |
| 685 | |
| 686 manager->MountPath(kSourcePath1, kSourceFormat, std::string(), | 852 manager->MountPath(kSourcePath1, kSourceFormat, std::string(), |
| 687 chromeos::MOUNT_TYPE_DEVICE, | 853 chromeos::MOUNT_TYPE_DEVICE, |
| 688 chromeos::MOUNT_ACCESS_MODE_READ_WRITE); | 854 chromeos::MOUNT_ACCESS_MODE_READ_WRITE); |
| 689 manager->MountPath(kSourcePath2, kSourceFormat, std::string(), | 855 manager->MountPath(kSourcePath2, kSourceFormat, std::string(), |
| 690 chromeos::MOUNT_TYPE_DEVICE, | 856 chromeos::MOUNT_TYPE_DEVICE, |
| 691 chromeos::MOUNT_ACCESS_MODE_READ_ONLY); | 857 chromeos::MOUNT_ACCESS_MODE_READ_ONLY); |
| 692 // Simulate cros_disks reporting mount completed. | 858 // Simulate cros_disks reporting mount completed. |
| 693 fake_cros_disks_client_->SendMountCompletedEvent( | 859 fake_cros_disks_client_->SendMountCompletedEvent( |
| 694 chromeos::MOUNT_ERROR_NONE, kSourcePath1, chromeos::MOUNT_TYPE_DEVICE, | 860 chromeos::MOUNT_ERROR_NONE, kSourcePath1, chromeos::MOUNT_TYPE_DEVICE, |
| 695 kMountPath1); | 861 kMountPath1); |
| 696 fake_cros_disks_client_->SendMountCompletedEvent( | 862 fake_cros_disks_client_->SendMountCompletedEvent( |
| 697 chromeos::MOUNT_ERROR_NONE, kSourcePath2, chromeos::MOUNT_TYPE_DEVICE, | 863 chromeos::MOUNT_ERROR_NONE, kSourcePath2, chromeos::MOUNT_TYPE_DEVICE, |
| 698 kMountPath2); | 864 kMountPath2); |
| 699 | 865 |
| 866 // Event handlers of observers should be called. | |
| 867 ASSERT_EQ(2U, observer_->GetEventCount()); | |
| 868 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING, | |
| 869 chromeos::MOUNT_ERROR_NONE, kMountPath1); | |
| 870 // For the 2nd source, the disk (block device) is not read-only but the | |
| 871 // test will mount it in read-only mode. | |
| 872 // Observers query |disks_| from |DiskMountManager| in its event handler for | |
| 873 // a mount completion event. Therefore |disks_| must be updated with correct | |
| 874 // |read_only| value before notifying to observers. | |
| 875 const MountEvent& secondMountEvent = observer_->GetMountEvent(1); | |
| 876 EXPECT_EQ(DiskMountManager::MOUNTING, secondMountEvent.event); | |
| 877 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, secondMountEvent.error_code); | |
| 878 EXPECT_EQ(kMountPath2, secondMountEvent.mount_point.mount_path); | |
| 879 // Verify if the disk appears read-only at the time of notification to | |
| 880 // observers. | |
| 881 EXPECT_TRUE(secondMountEvent.disk->is_read_only()); | |
| 882 | |
| 883 // Verify the final state of manager->disks. | |
| 700 const DiskMountManager::DiskMap& disks = manager->disks(); | 884 const DiskMountManager::DiskMap& disks = manager->disks(); |
| 701 ASSERT_GT(disks.count(kSourcePath1), 0U); | 885 ASSERT_GT(disks.count(kSourcePath1), 0U); |
| 702 EXPECT_FALSE(disks.find(kSourcePath1)->second->is_read_only()); | 886 EXPECT_FALSE(disks.find(kSourcePath1)->second->is_read_only()); |
| 703 ASSERT_GT(disks.count(kSourcePath2), 0U); | 887 ASSERT_GT(disks.count(kSourcePath2), 0U); |
| 704 EXPECT_TRUE(disks.find(kSourcePath2)->second->is_read_only()); | 888 EXPECT_TRUE(disks.find(kSourcePath2)->second->is_read_only()); |
| 705 } | 889 } |
| 706 | 890 |
| 707 TEST_F(DiskMountManagerTest, MountPath_ReadOnlyDevice) { | 891 TEST_F(DiskMountManagerTest, MountPath_ReadOnlyDevice) { |
| 708 DiskMountManager* manager = DiskMountManager::GetInstance(); | 892 DiskMountManager* manager = DiskMountManager::GetInstance(); |
| 709 const std::string kSourceFormat = std::string(); | 893 const std::string kSourceFormat = std::string(); |
| 710 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE | 894 const std::string kMountLabel = std::string(); // N/A for MOUNT_TYPE_DEVICE |
| 711 | 895 |
| 712 // Event handlers of observers should be called. | |
| 713 EXPECT_CALL( | |
| 714 observer_, | |
| 715 OnMountEvent(DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE, | |
| 716 Field(&DiskMountManager::MountPointInfo::mount_path, | |
| 717 kReadOnlyMountpath))); | |
| 718 | |
| 719 // Attempt to mount a read-only device in read-write mode. | 896 // Attempt to mount a read-only device in read-write mode. |
| 720 manager->MountPath(kReadOnlyDeviceSource, kSourceFormat, std::string(), | 897 manager->MountPath(kReadOnlyDeviceSource, kSourceFormat, std::string(), |
| 721 chromeos::MOUNT_TYPE_DEVICE, | 898 chromeos::MOUNT_TYPE_DEVICE, |
| 722 chromeos::MOUNT_ACCESS_MODE_READ_WRITE); | 899 chromeos::MOUNT_ACCESS_MODE_READ_WRITE); |
| 723 // Simulate cros_disks reporting mount completed. | 900 // Simulate cros_disks reporting mount completed. |
| 724 fake_cros_disks_client_->SendMountCompletedEvent( | 901 fake_cros_disks_client_->SendMountCompletedEvent( |
| 725 chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceSource, | 902 chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceSource, |
| 726 chromeos::MOUNT_TYPE_DEVICE, kReadOnlyMountpath); | 903 chromeos::MOUNT_TYPE_DEVICE, kReadOnlyMountpath); |
| 727 | 904 |
| 905 // Event handlers of observers should be called. | |
| 906 ASSERT_EQ(1U, observer_->GetEventCount()); | |
| 907 VerifyMountEvent(observer_->GetMountEvent(0), DiskMountManager::MOUNTING, | |
| 908 chromeos::MOUNT_ERROR_NONE, kReadOnlyMountpath); | |
| 728 const DiskMountManager::DiskMap& disks = manager->disks(); | 909 const DiskMountManager::DiskMap& disks = manager->disks(); |
| 729 ASSERT_GT(disks.count(kReadOnlyDeviceSource), 0U); | 910 ASSERT_GT(disks.count(kReadOnlyDeviceSource), 0U); |
| 730 // The mounted disk should preserve the read-only flag of the block device. | 911 // The mounted disk should preserve the read-only flag of the block device. |
| 731 EXPECT_TRUE(disks.find(kReadOnlyDeviceSource)->second->is_read_only()); | 912 EXPECT_TRUE(disks.find(kReadOnlyDeviceSource)->second->is_read_only()); |
| 732 } | 913 } |
| 733 | 914 |
| 734 } // namespace | 915 } // namespace |
| OLD | NEW |