// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_cros_disks_client.h"
#include "chromeos/disks/disk_mount_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using chromeos::disks::DiskMountManager;
using chromeos::CrosDisksClient;
using chromeos::DBusThreadManager;
using chromeos::FakeCrosDisksClient;
using testing::_;
using testing::Field;
using testing::InSequence;
using testing::InvokeWithoutArgs;

namespace {

const char kReadOnlyMountpath[] = "/device/read_only_mount_path";
const char kReadOnlyDeviceSource[] = "/device/read_only_source_path";

// Holds information needed to create a DiskMountManager::Disk instance.
struct TestDiskInfo {
  const char* source_path;
  const char* mount_path;
  const char* system_path;
  const char* file_path;
  const char* device_label;
  const char* drive_label;
  const char* vendor_id;
  const char* vendor_name;
  const char* product_id;
  const char* product_name;
  const char* fs_uuid;
  const char* system_path_prefix;
  chromeos::DeviceType device_type;
  uint64_t size_in_bytes;
  bool is_parent;
  bool is_read_only;
  bool has_media;
  bool on_boot_device;
  bool on_removable_device;
  bool is_hidden;
};

// Holds information to create a DiskMOuntManager::MountPointInfo instance.
struct TestMountPointInfo {
  const char* source_path;
  const char* mount_path;
  chromeos::MountType mount_type;
  chromeos::disks::MountCondition mount_condition;
};

// List of disks held in DiskMountManager at the begining of the test.
const TestDiskInfo kTestDisks[] = {
  {
    "/device/source_path",
    "/device/mount_path",
    "/device/prefix/system_path",
    "/device/file_path",
    "/device/device_label",
    "/device/drive_label",
    "/device/vendor_id",
    "/device/vendor_name",
    "/device/product_id",
    "/device/product_name",
    "/device/fs_uuid",
    "/device/prefix",
    chromeos::DEVICE_TYPE_USB,
    1073741824,  // size in bytes
    false,       // is parent
    false,       // is read only
    true,        // has media
    false,       // is on boot device
    true,        // is on removable device
    false        // is hidden
  },
  {
    "/device/source_path2",
    "/device/mount_path2",
    "/device/prefix/system_path2",
    "/device/file_path2",
    "/device/device_label2",
    "/device/drive_label2",
    "/device/vendor_id2",
    "/device/vendor_name2",
    "/device/product_id2",
    "/device/product_name2",
    "/device/fs_uuid2",
    "/device/prefix2",
    chromeos::DEVICE_TYPE_SD,
    1073741824,  // size in bytes
    false,       // is parent
    false,       // is read only
    true,        // has media
    false,       // is on boot device
    true,        // is on removable device
    false        // is hidden
  },
  {
    kReadOnlyDeviceSource,
    kReadOnlyMountpath,
    "/device/prefix/system_path_3",
    "/device/file_path_3",
    "/device/device_label_3",
    "/device/drive_label_3",
    "/device/vendor_id_3",
    "/device/vendor_name_3",
    "/device/product_id_3",
    "/device/product_name_3",
    "/device/fs_uuid_3",
    "/device/prefix",
    chromeos::DEVICE_TYPE_USB,
    1073741824,  // size in bytes
    false,       // is parent
    true,        // is read only
    true,        // has media
    false,       // is on boot device
    true,        // is on removable device
    false        // is hidden
  },
};

// List of mount points  held in DiskMountManager at the begining of the test.
const TestMountPointInfo kTestMountPoints[] = {
  {
    "/archive/source_path",
    "/archive/mount_path",
    chromeos::MOUNT_TYPE_ARCHIVE,
    chromeos::disks::MOUNT_CONDITION_NONE
  },
  {
    "/device/source_path",
    "/device/mount_path",
    chromeos::MOUNT_TYPE_DEVICE,
    chromeos::disks::MOUNT_CONDITION_NONE
  },
  {
    kReadOnlyDeviceSource,
    kReadOnlyMountpath,
    chromeos::MOUNT_TYPE_DEVICE,
    chromeos::disks::MOUNT_CONDITION_NONE
  },
};

// Mocks DiskMountManager observer.
class MockDiskMountManagerObserver : public DiskMountManager::Observer {
 public:
  virtual ~MockDiskMountManagerObserver() {}

  MOCK_METHOD2(OnDiskEvent, void(DiskMountManager::DiskEvent event,
                                 const DiskMountManager::Disk* disk));
  MOCK_METHOD2(OnDeviceEvent, void(DiskMountManager::DeviceEvent event,
                                   const std::string& device_path));
  MOCK_METHOD3(OnMountEvent,
      void(DiskMountManager::MountEvent event,
           chromeos::MountError error_code,
           const DiskMountManager::MountPointInfo& mount_point));
  MOCK_METHOD3(OnFormatEvent,
      void(DiskMountManager::FormatEvent event,
           chromeos::FormatError error_code,
           const std::string& device_path));
};

// Expect |is_read_only| value of a disk object keyed by |source_path|.
void ExpectDiskReadOnly(const DiskMountManager* manager,
                        const std::string& source_path,
                        bool expected) {
  EXPECT_EQ(expected,
            manager->disks().find(source_path)->second->is_read_only());
}

class DiskMountManagerTest : public testing::Test {
 public:
  DiskMountManagerTest() {}
  ~DiskMountManagerTest() override {}

  // Sets up test dbus tread manager and disks mount manager.
  // Initializes disk mount manager disks and mount points.
  // Adds a test observer to the disk mount manager.
  void SetUp() override {
    fake_cros_disks_client_ = new FakeCrosDisksClient;
    DBusThreadManager::GetSetterForTesting()->SetCrosDisksClient(
        std::unique_ptr<CrosDisksClient>(fake_cros_disks_client_));

    DiskMountManager::Initialize();

    InitDisksAndMountPoints();

    DiskMountManager::GetInstance()->AddObserver(&observer_);
  }

  // Shuts down dbus thread manager and disk moutn manager used in the test.
  void TearDown() override {
    DiskMountManager::GetInstance()->RemoveObserver(&observer_);
    DiskMountManager::Shutdown();
    DBusThreadManager::Shutdown();
  }

 protected:
  // Checks if disk mount manager contains a mount point with specified moutn
  // path.
  bool HasMountPoint(const std::string& mount_path) {
    const DiskMountManager::MountPointMap& mount_points =
        DiskMountManager::GetInstance()->mount_points();
    return mount_points.find(mount_path) != mount_points.end();
  }

 private:
  // Adds a new disk to the disk mount manager.
  void AddTestDisk(const TestDiskInfo& disk) {
    EXPECT_TRUE(DiskMountManager::GetInstance()->AddDiskForTest(
        new DiskMountManager::Disk(disk.source_path,
                                   disk.mount_path,
                                   disk.system_path,
                                   disk.file_path,
                                   disk.device_label,
                                   disk.drive_label,
                                   disk.vendor_id,
                                   disk.vendor_name,
                                   disk.product_id,
                                   disk.product_name,
                                   disk.fs_uuid,
                                   disk.system_path_prefix,
                                   disk.device_type,
                                   disk.size_in_bytes,
                                   disk.is_parent,
                                   disk.is_read_only,
                                   disk.has_media,
                                   disk.on_boot_device,
                                   disk.on_removable_device,
                                   disk.is_hidden)));
  }

  // Adds a new mount point to the disk mount manager.
  // If the moutn point is a device mount point, disk with its source path
  // should already be added to the disk mount manager.
  void AddTestMountPoint(const TestMountPointInfo& mount_point) {
    EXPECT_TRUE(DiskMountManager::GetInstance()->AddMountPointForTest(
        DiskMountManager::MountPointInfo(mount_point.source_path,
                                         mount_point.mount_path,
                                         mount_point.mount_type,
                                         mount_point.mount_condition)));
  }

  // Adds disks and mount points to disk mount manager.
  void InitDisksAndMountPoints() {
    // Disks should be  added first (when adding device mount points it is
    // expected that the corresponding disk is already added).
    for (size_t i = 0; i < arraysize(kTestDisks); i++)
      AddTestDisk(kTestDisks[i]);

    for (size_t i = 0; i < arraysize(kTestMountPoints); i++)
      AddTestMountPoint(kTestMountPoints[i]);
  }

 protected:
  chromeos::FakeCrosDisksClient* fake_cros_disks_client_;
  MockDiskMountManagerObserver observer_;
  base::MessageLoopForUI message_loop_;
};

// Tests that the observer gets notified on attempt to format non existent mount
// point.
TEST_F(DiskMountManagerTest, Format_NotMounted) {
  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                       chromeos::FORMAT_ERROR_UNKNOWN,
                                       "/mount/non_existent"))
      .Times(1);
  DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent");
}

// Tests that the observer gets notified on attempt to format read-only mount
// point.
TEST_F(DiskMountManagerTest, Format_ReadOnly) {
  EXPECT_CALL(observer_,
              OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                            chromeos::FORMAT_ERROR_DEVICE_NOT_ALLOWED,
                            kReadOnlyMountpath))
      .Times(1);
  DiskMountManager::GetInstance()->FormatMountedDevice(kReadOnlyMountpath);
}

// Tests that it is not possible to format archive mount point.
TEST_F(DiskMountManagerTest, Format_Archive) {
  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                       chromeos::FORMAT_ERROR_UNKNOWN,
                                       "/archive/source_path"))
      .Times(1);

  DiskMountManager::GetInstance()->FormatMountedDevice("/archive/mount_path");
}

// Tests that format fails if the device cannot be unmounted.
TEST_F(DiskMountManagerTest, Format_FailToUnmount) {
  // Before formatting mounted device, the device should be unmounted.
  // In this test unmount will fail, and there should be no attempt to
  // format the device.

  // Set up expectations for observer mock.
  // Observer should be notified that unmount attempt fails and format task
  // failed to start.
  {
    InSequence s;

    EXPECT_CALL(observer_,
        OnMountEvent(DiskMountManager::UNMOUNTING,
                     chromeos::MOUNT_ERROR_INTERNAL,
                     Field(&DiskMountManager::MountPointInfo::mount_path,
                           "/device/mount_path")))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                         chromeos::FORMAT_ERROR_UNKNOWN,
                                         "/device/source_path"))
        .Times(1);
  }

  fake_cros_disks_client_->MakeUnmountFail();
  // Start test.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(0, fake_cros_disks_client_->format_call_count());

  // The device mount should still be here.
  EXPECT_TRUE(HasMountPoint("/device/mount_path"));
}

// Tests that observer is notified when cros disks fails to start format
// process.
TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) {
  // Before formatting mounted device, the device should be unmounted.
  // In this test, unmount will succeed, but call to Format method will
  // fail.

  // Set up expectations for observer mock.
  // Observer should be notified that the device was unmounted and format task
  // failed to start.
  {
    InSequence s;

    EXPECT_CALL(observer_,
        OnMountEvent(DiskMountManager::UNMOUNTING,
                     chromeos::MOUNT_ERROR_NONE,
                     Field(&DiskMountManager::MountPointInfo::mount_path,
                           "/device/mount_path")))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                         chromeos::FORMAT_ERROR_UNKNOWN,
                                         "/device/source_path"))
        .Times(1);
  }

  fake_cros_disks_client_->MakeFormatFail();
  // Start the test.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  EXPECT_EQ("/device/source_path",
            fake_cros_disks_client_->last_format_device_path());
  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());

  // The device mount should be gone.
  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
}

// Tests the case where there are two format requests for the same device.
TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) {
  // Only the first format request should be processed (the second unmount
  // request fails because the device is already unmounted at that point).
  // CrosDisksClient will report that the format process for the first request
  // is successfully started.

  // Set up expectations for observer mock.
  // The observer should get a FORMAT_STARTED event for one format request and a
  // FORMAT_COMPLETED with an error code for the other format request. The
  // formatting will be started only for the first request.
  // There should be only one UNMOUNTING event. The result of the second one
  // should not be reported as the mount point will go away after the first
  // request.
  //
  // Note that in this test the format completion signal will not be simulated,
  // so the observer should not get FORMAT_COMPLETED signal.
  {
    InSequence s;

    EXPECT_CALL(observer_,
        OnMountEvent(DiskMountManager::UNMOUNTING,
                     chromeos::MOUNT_ERROR_NONE,
                     Field(&DiskMountManager::MountPointInfo::mount_path,
                           "/device/mount_path")))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                         chromeos::FORMAT_ERROR_UNKNOWN,
                                         "/device/source_path"))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
                                         chromeos::FORMAT_ERROR_NONE,
                                         "/device/source_path"))
        .Times(1);
  }

  fake_cros_disks_client_->set_unmount_listener(
      base::Bind(&FakeCrosDisksClient::MakeUnmountFail,
                 base::Unretained(fake_cros_disks_client_)));
  // Start the test.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Cros disks will respond asynchronoulsy, so let's drain the message loop.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  EXPECT_EQ("/device/source_path",
            fake_cros_disks_client_->last_format_device_path());
  EXPECT_EQ("vfat",
            fake_cros_disks_client_->last_format_filesystem());

  // The device mount should be gone.
  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
}

// Tests the case when the format process actually starts and fails.
TEST_F(DiskMountManagerTest, Format_FormatFails) {
  // Both unmount and format device cals are successful in this test.

  // Set up expectations for observer mock.
  // The observer should get notified that the device was unmounted and that
  // formatting has started.
  // After the formatting starts, the test will simulate failing
  // FORMAT_COMPLETED signal, so the observer should also be notified the
  // formatting has failed (FORMAT_COMPLETED event).
  {
    InSequence s;

    EXPECT_CALL(observer_,
        OnMountEvent(DiskMountManager::UNMOUNTING,
                     chromeos::MOUNT_ERROR_NONE,
                     Field(&DiskMountManager::MountPointInfo::mount_path,
                           "/device/mount_path")))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
                                         chromeos::FORMAT_ERROR_NONE,
                                         "/device/source_path"))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                         chromeos::FORMAT_ERROR_UNKNOWN,
                                         "/device/source_path"))
        .Times(1);
  }

  // Start the test.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Wait for Unmount and Format calls to end.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  EXPECT_EQ("/device/source_path",
            fake_cros_disks_client_->last_format_device_path());
  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());

  // The device should be unmounted by now.
  EXPECT_FALSE(HasMountPoint("/device/mount_path"));

  // Send failing FORMAT_COMPLETED signal.
  // The failure is marked by ! in fromt of the path (but this should change
  // soon).
  fake_cros_disks_client_->SendFormatCompletedEvent(
      chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path");
}

// Tests the case when formatting completes successfully.
TEST_F(DiskMountManagerTest, Format_FormatSuccess) {
  // Set up cros disks client mocks.
  // Both unmount and format device cals are successful in this test.

  // Set up expectations for observer mock.
  // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
  // events (all of them without an error set).
  {
    InSequence s;

    EXPECT_CALL(observer_,
        OnMountEvent(DiskMountManager::UNMOUNTING,
                     chromeos::MOUNT_ERROR_NONE,
                     Field(&DiskMountManager::MountPointInfo::mount_path,
                           "/device/mount_path")))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
                                         chromeos::FORMAT_ERROR_NONE,
                                         "/device/source_path"))
        .Times(1);

    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                         chromeos::FORMAT_ERROR_NONE,
                                         "/device/source_path"))
        .Times(1);
  }

  // Start the test.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Wait for Unmount and Format calls to end.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  EXPECT_EQ("/device/source_path",
            fake_cros_disks_client_->last_format_device_path());
  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());

  // The device should be unmounted by now.
  EXPECT_FALSE(HasMountPoint("/device/mount_path"));

  // Simulate cros_disks reporting success.
  fake_cros_disks_client_->SendFormatCompletedEvent(
      chromeos::FORMAT_ERROR_NONE, "/device/source_path");
}

// Tests that it's possible to format the device twice in a row (this may not be
// true if the list of pending formats is not properly cleared).
TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) {
  // All unmount and format device cals are successful in this test.
  // Each of the should be made twice (once for each formatting task).

  // Set up expectations for observer mock.
  // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
  // events (all of them without an error set) twice (once for each formatting
  // task).
  // Also, there should be a MOUNTING event when the device remounting is
  // simulated.
  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                       chromeos::FORMAT_ERROR_NONE,
                                       "/device/source_path"))
      .Times(2);

  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
                                       chromeos::FORMAT_ERROR_NONE,
                                       "/device/source_path"))
      .Times(2);

  EXPECT_CALL(observer_,
      OnMountEvent(DiskMountManager::UNMOUNTING,
                   chromeos::MOUNT_ERROR_NONE,
                   Field(&DiskMountManager::MountPointInfo::mount_path,
                         "/device/mount_path")))
      .Times(2);

  EXPECT_CALL(observer_,
      OnMountEvent(DiskMountManager::MOUNTING,
                   chromeos::MOUNT_ERROR_NONE,
                   Field(&DiskMountManager::MountPointInfo::mount_path,
                         "/device/mount_path")))
      .Times(1);

  // Start the test.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Wait for Unmount and Format calls to end.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
  EXPECT_EQ("/device/source_path",
            fake_cros_disks_client_->last_format_device_path());
  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());

  // The device should be unmounted by now.
  EXPECT_FALSE(HasMountPoint("/device/mount_path"));

  // Simulate cros_disks reporting success.
  fake_cros_disks_client_->SendFormatCompletedEvent(
      chromeos::FORMAT_ERROR_NONE, "/device/source_path");

  // Simulate the device remounting.
  fake_cros_disks_client_->SendMountCompletedEvent(
      chromeos::MOUNT_ERROR_NONE,
      "/device/source_path",
      chromeos::MOUNT_TYPE_DEVICE,
      "/device/mount_path");

  EXPECT_TRUE(HasMountPoint("/device/mount_path"));

  // Try formatting again.
  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");

  // Wait for Unmount and Format calls to end.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
  EXPECT_EQ("/device/mount_path",
            fake_cros_disks_client_->last_unmount_device_path());
  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
            fake_cros_disks_client_->last_unmount_options());
  EXPECT_EQ(2, fake_cros_disks_client_->format_call_count());
  EXPECT_EQ("/device/source_path",
            fake_cros_disks_client_->last_format_device_path());
  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());

  // Simulate cros_disks reporting success.
  fake_cros_disks_client_->SendFormatCompletedEvent(
      chromeos::FORMAT_ERROR_NONE, "/device/source_path");
}

TEST_F(DiskMountManagerTest, MountPath_RecordAccessMode) {
  DiskMountManager* manager = DiskMountManager::GetInstance();
  const std::string kSourcePath1 = "/device/source_path";
  const std::string kSourcePath2 = "/device/source_path2";
  const std::string kSourceFormat = std::string();
  const std::string kMountLabel = std::string();  // N/A for MOUNT_TYPE_DEVICE
  // For MountCompleted. Must be non-empty strings.
  const std::string kMountPath1 = "/media/foo";
  const std::string kMountPath2 = "/media/bar";

  // Event handlers of observers should be called.
  EXPECT_CALL(
      observer_,
      OnMountEvent(
          DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
          Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1)));
  // For the 2nd source, the disk (block device) is not read-only but the
  // test will mount it in read-only mode.
  // Observers query |disks_| from |DiskMountManager| in its event handler for
  // a mount completion event. Therefore |disks_| must be updated with correct
  // |read_only| value before notifying to observers.
  EXPECT_CALL(
      observer_,
      OnMountEvent(
          DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
          Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath2)))
      .WillOnce(InvokeWithoutArgs(
          // Verify if the disk appears read-only at the time of notification
          // to observers.
          [&]() { ExpectDiskReadOnly(manager, kSourcePath2, true); }));

  manager->MountPath(kSourcePath1, kSourceFormat, std::string(),
                     chromeos::MOUNT_TYPE_DEVICE,
                     chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
  manager->MountPath(kSourcePath2, kSourceFormat, std::string(),
                     chromeos::MOUNT_TYPE_DEVICE,
                     chromeos::MOUNT_ACCESS_MODE_READ_ONLY);
  // Simulate cros_disks reporting mount completed.
  fake_cros_disks_client_->SendMountCompletedEvent(
      chromeos::MOUNT_ERROR_NONE, kSourcePath1, chromeos::MOUNT_TYPE_DEVICE,
      kMountPath1);
  fake_cros_disks_client_->SendMountCompletedEvent(
      chromeos::MOUNT_ERROR_NONE, kSourcePath2, chromeos::MOUNT_TYPE_DEVICE,
      kMountPath2);

  const DiskMountManager::DiskMap& disks = manager->disks();
  ASSERT_GT(disks.count(kSourcePath1), 0U);
  EXPECT_FALSE(disks.find(kSourcePath1)->second->is_read_only());
  ASSERT_GT(disks.count(kSourcePath2), 0U);
  EXPECT_TRUE(disks.find(kSourcePath2)->second->is_read_only());
}

TEST_F(DiskMountManagerTest, MountPath_ReadOnlyDevice) {
  DiskMountManager* manager = DiskMountManager::GetInstance();
  const std::string kSourceFormat = std::string();
  const std::string kMountLabel = std::string();  // N/A for MOUNT_TYPE_DEVICE

  // Event handlers of observers should be called.
  EXPECT_CALL(
      observer_,
      OnMountEvent(DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
                   Field(&DiskMountManager::MountPointInfo::mount_path,
                         kReadOnlyMountpath)));

  // Attempt to mount a read-only device in read-write mode.
  manager->MountPath(kReadOnlyDeviceSource, kSourceFormat, std::string(),
                     chromeos::MOUNT_TYPE_DEVICE,
                     chromeos::MOUNT_ACCESS_MODE_READ_WRITE);
  // Simulate cros_disks reporting mount completed.
  fake_cros_disks_client_->SendMountCompletedEvent(
      chromeos::MOUNT_ERROR_NONE, kReadOnlyDeviceSource,
      chromeos::MOUNT_TYPE_DEVICE, kReadOnlyMountpath);

  const DiskMountManager::DiskMap& disks = manager->disks();
  ASSERT_GT(disks.count(kReadOnlyDeviceSource), 0U);
  // The mounted disk should preserve the read-only flag of the block device.
  EXPECT_TRUE(disks.find(kReadOnlyDeviceSource)->second->is_read_only());
}

}  // namespace
