// Copyright (c) 2012 The Chromium OS 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 "cros-disks/disk_manager.h"

#include <stdlib.h>
#include <sys/mount.h>
#include <time.h>

#include <map>
#include <memory>
#include <utility>

#include <base/callback.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/stl_util.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/test/task_environment.h>
#include <brillo/process/process_reaper.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "cros-disks/device_ejector.h"
#include "cros-disks/disk.h"
#include "cros-disks/disk_monitor.h"
#include "cros-disks/fuse_mounter.h"
#include "cros-disks/metrics.h"
#include "cros-disks/mount_point.h"
#include "cros-disks/mounter.h"
#include "cros-disks/platform.h"
#include "cros-disks/system_mounter.h"

namespace cros_disks {
namespace {

using testing::_;
using testing::AllOf;
using testing::Contains;
using testing::DoAll;
using testing::DoDefault;
using testing::ElementsAre;
using testing::HasSubstr;
using testing::Invoke;
using testing::Return;
using testing::SaveArg;
using testing::StrEq;

const uint64_t kExpectedMountFlags =
    MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_NOSYMFOLLOW;

class MockDeviceEjector : public DeviceEjector {
 public:
  MockDeviceEjector() : DeviceEjector(nullptr) {}

  MOCK_METHOD(bool, Eject, (const std::string&), (override));
};

class FakeDiskMonitor : public DiskMonitor {
 public:
  FakeDiskMonitor() = default;

  bool Initialize() override { return true; }

  std::vector<Disk> EnumerateDisks() const override { return disks_; }

  bool GetDiskByDevicePath(const base::FilePath& path,
                           Disk* disk) const override {
    for (const auto& d : disks_) {
      if (d.device_file == path.value()) {
        if (disk)
          *disk = d;
        return true;
      }
    }
    return false;
  }

  std::vector<Disk> disks_;
};

class MockPlatform : public Platform {
 public:
  MockPlatform() = default;

  MOCK_METHOD(MountErrorType,
              Unmount,
              (const std::string&, int),
              (const, override));

  MOCK_METHOD(MountErrorType,
              Mount,
              (const std::string& source,
               const std::string& target,
               const std::string& filesystem_type,
               uint64_t flags,
               const std::string& options),
              (const, override));

  MOCK_METHOD(bool, PathExists, (const std::string& path), (const, override));
  bool PathExistsImpl(const std::string& path) const {
    return Platform::PathExists(path);
  }

  bool Lstat(const std::string& path,
             base::stat_wrapper_t* out) const override {
    if (base::StartsWith(path, "/dev/", base::CompareCase::SENSITIVE)) {
      out->st_mode = S_IFBLK | 0640;
      return true;
    }
    NOTREACHED();
    return false;
  }

  bool SetOwnership(const std::string& path,
                    uid_t user_id,
                    gid_t group_id) const override {
    return true;
  }

  bool SetPermissions(const std::string& path, mode_t mode) const override {
    return true;
  }

  bool GetUserAndGroupId(const std::string& user_name,
                         uid_t* user_id,
                         gid_t* group_id) const override {
    if (user_name == "fuse-exfat") {
      *user_id = 111;
      *group_id = 222;
      return true;
    }
    if (user_name == "ntfs-3g") {
      *user_id = 333;
      *group_id = 444;
      return true;
    }
    NOTREACHED();
    return false;
  }
};

class MockSandboxedProcess : public SandboxedProcess {
 public:
  pid_t StartImpl(base::ScopedFD, base::ScopedFD) override {
    OnStart(arguments());
    return 123;
  }
  int WaitImpl() override { return WaitNonBlockingImpl(); }
  int WaitNonBlockingImpl() override { return 0; }
  MOCK_METHOD(void, OnStart, (const std::vector<std::string>& args), (const));
  using SandboxedProcess::OnLauncherExit;
};

}  // namespace

class DiskManagerTest : public ::testing::Test, public SandboxedProcessFactory {
 public:
  DiskManagerTest() {}

  void SetUp() override {
    CHECK(dir_.CreateUniqueTempDir());
    ON_CALL(platform_, PathExists)
        .WillByDefault(Invoke(&platform_, &MockPlatform::PathExistsImpl));
    ON_CALL(platform_, PathExists("/dev/sda1")).WillByDefault(Return(true));
    manager_ = std::make_unique<DiskManager>(dir_.GetPath().value(), &platform_,
                                             &metrics_, &process_reaper_,
                                             &monitor_, &ejector_, this);
    CHECK(manager_->Initialize());
  }

 protected:
  std::unique_ptr<SandboxedProcess> CreateSandboxedProcess() const override {
    auto ptr = std::make_unique<MockSandboxedProcess>();
    process_ = ptr.get();
    ON_CALL(*ptr, OnStart).WillByDefault(SaveArg<0>(&fuse_args_));
    return ptr;
  }

  void OnMountCompleted(const std::string& path, MountErrorType error) {
    EXPECT_FALSE(mount_completed_);
    mount_path_ = path;
    mount_error_ = error;
    mount_completed_ = true;
  }

  MountManager::MountCallback GetMountCallback() {
    mount_path_.clear();
    mount_error_ = MOUNT_ERROR_NONE;
    mount_completed_ = false;

    return base::BindOnce(&DiskManagerTest::OnMountCompleted,
                          base::Unretained(this));
  }

  using Environment = base::test::TaskEnvironment;
  Environment task_environment_{Environment::MainThreadType::IO};
  base::ScopedTempDir dir_;
  Metrics metrics_;
  MockPlatform platform_;
  brillo::ProcessReaper process_reaper_;
  MockDeviceEjector ejector_;
  FakeDiskMonitor monitor_;
  std::unique_ptr<DiskManager> manager_;
  mutable MockSandboxedProcess* process_ = nullptr;
  mutable std::vector<std::string> fuse_args_;
  std::string mount_path_;
  MountErrorType mount_error_;
  bool mount_completed_;
};

MATCHER_P(HasBits, bits, "") {
  return bits == (bits & arg);
}

TEST_F(DiskManagerTest, MountBootDeviceNotAllowed) {
  EXPECT_CALL(platform_, Mount).Times(0);
  EXPECT_CALL(platform_, Unmount).Times(0);
  manager_->Mount("/dev/sda1", "vfat", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_INVALID_DEVICE_PATH, mount_error_);
  monitor_.disks_.push_back({
      .is_on_boot_device = true,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
  });
  manager_->Mount("/dev/sda1", "vfat", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_INVALID_DEVICE_PATH, mount_error_);
}

TEST_F(DiskManagerTest, MountNonExistingDevice) {
  EXPECT_CALL(platform_, Mount).Times(0);
  EXPECT_CALL(platform_, Unmount).Times(0);
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
  });
  EXPECT_CALL(platform_, PathExists("/dev/sda1")).WillRepeatedly(Return(false));
  manager_->Mount("/dev/sda1", "vfat", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_INVALID_DEVICE_PATH, mount_error_);
}

TEST_F(DiskManagerTest, MountUsesLabel) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "vfat", _, _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  EXPECT_EQ("foo", base::FilePath(mount_path_).BaseName().value());

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountFAT) {
  // Override the time zone to make this test deterministic.
  // This test uses AWST (Perth, Australia), which is UTC+8, as the test time
  // zone. However, the TZ environment variable is the time to be added to local
  // time to get to UTC, hence the negative.
  setenv("TZ", "UTC-8", 1);

  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
  });

  std::string opts;
  EXPECT_CALL(platform_,
              Mount("/dev/sda1", _, "vfat", HasBits(kExpectedMountFlags), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  auto options =
      base::SplitString(opts, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  EXPECT_THAT(options,
              AllOf(Contains("uid=1000"), Contains("gid=1001"),
                    Contains("shortname=mixed"), Contains("time_offset=480")));

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountExFAT) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "exfat",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "fuseblk.exfat",
                               HasBits(kExpectedMountFlags), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());

  // Simulate asynchronous termination of FUSE launcher process.
  EXPECT_FALSE(mount_completed_);
  process_->OnLauncherExit();

  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  auto options =
      base::SplitString(opts, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  EXPECT_THAT(options,
              AllOf(Contains("user_id=1000"), Contains("group_id=1001")));
  EXPECT_THAT(fuse_args_,
              ElementsAre("/usr/sbin/mount.exfat-fuse", "-o",
                          HasSubstr("dmask=0027,fmask=0027,uid=1000,gid=1001"),
                          "/dev/sda1", _));

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountNTFS) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "ntfs",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "fuseblk.ntfs",
                               HasBits(kExpectedMountFlags), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());

  // Simulate asynchronous termination of FUSE launcher process.
  EXPECT_FALSE(mount_completed_);
  process_->OnLauncherExit();

  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  auto options =
      base::SplitString(opts, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  EXPECT_THAT(options,
              AllOf(Contains("user_id=1000"), Contains("group_id=1001")));
  EXPECT_THAT(fuse_args_,
              ElementsAre("/usr/bin/ntfs-3g", "-o",
                          HasSubstr("dmask=0027,fmask=0027,uid=1000,gid=1001"),
                          "/dev/sda1", _));

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountCD) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "iso9660",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "iso9660",
                               HasBits(kExpectedMountFlags | MS_RDONLY), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  auto options =
      base::SplitString(opts, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  EXPECT_THAT(options, AllOf(Contains("uid=1000"), Contains("gid=1001")));

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountDVD) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "udf",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "udf",
                               HasBits(kExpectedMountFlags | MS_RDONLY), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  auto options =
      base::SplitString(opts, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  EXPECT_THAT(options, AllOf(Contains("uid=1000"), Contains("gid=1001")));

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountHFS) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "hfsplus",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_,
              Mount("/dev/sda1", _, "hfsplus", HasBits(kExpectedMountFlags), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);
  auto options =
      base::SplitString(opts, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  EXPECT_THAT(options, AllOf(Contains("uid=1000"), Contains("gid=1001")));

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountReadOnlyMedia) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .is_read_only = true,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "vfat",
                               HasBits(kExpectedMountFlags | MS_RDONLY), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountForcedReadOnly) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
      .label = "foo",
  });

  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "vfat",
                               HasBits(kExpectedMountFlags | MS_RDONLY), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));
  manager_->Mount("/dev/sda1", "", {"ro"}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, MountRetryReadOnlyIfFailed) {
  monitor_.disks_.push_back({
      .is_on_boot_device = false,
      .device_file = "/dev/sda1",
      .filesystem_type = "vfat",
      .label = "foo",
  });

  EXPECT_CALL(platform_,
              Mount("/dev/sda1", _, "vfat", HasBits(kExpectedMountFlags), _))
      .WillOnce(Return(MOUNT_ERROR_PATH_NOT_MOUNTED));
  std::string opts;
  EXPECT_CALL(platform_, Mount("/dev/sda1", _, "vfat",
                               HasBits(kExpectedMountFlags | MS_RDONLY), _))
      .WillOnce(DoAll(SaveArg<4>(&opts), Return(MOUNT_ERROR_NONE)));

  manager_->Mount("/dev/sda1", "", {}, GetMountCallback());
  EXPECT_TRUE(mount_completed_);
  EXPECT_EQ(MOUNT_ERROR_NONE, mount_error_);

  EXPECT_CALL(platform_, Unmount(mount_path_, _))
      .WillOnce(Return(MOUNT_ERROR_NONE));
  MountErrorType err = manager_->Unmount("/dev/sda1");
  EXPECT_EQ(MOUNT_ERROR_NONE, err);
}

TEST_F(DiskManagerTest, CanMount) {
  EXPECT_TRUE(manager_->CanMount("/dev/sda1"));
  EXPECT_TRUE(manager_->CanMount("/devices/block/sda/sda1"));
  EXPECT_TRUE(manager_->CanMount("/sys/devices/block/sda/sda1"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/disk1"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/disk1/"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/disk 1"));
  EXPECT_FALSE(manager_->CanMount("/media/archive/test.zip"));
  EXPECT_FALSE(manager_->CanMount("/media/archive/test.zip/"));
  EXPECT_FALSE(manager_->CanMount("/media/archive/test 1.zip"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/disk1/test.zip"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/disk1/test 1.zip"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/disk1/dir1/test.zip"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/test.zip/test1.zip"));
  EXPECT_FALSE(manager_->CanMount("/home/chronos/user/Downloads/test1.zip"));
  EXPECT_FALSE(manager_->CanMount("/home/chronos/user/GCache/test1.zip"));
  EXPECT_FALSE(
      manager_->CanMount("/home/chronos"
                         "/u-0123456789abcdef0123456789abcdef01234567"
                         "/Downloads/test1.zip"));
  EXPECT_FALSE(
      manager_->CanMount("/home/chronos"
                         "/u-0123456789abcdef0123456789abcdef01234567"
                         "/GCache/test1.zip"));
  EXPECT_FALSE(manager_->CanMount(""));
  EXPECT_FALSE(manager_->CanMount("/tmp"));
  EXPECT_FALSE(manager_->CanMount("/media/removable"));
  EXPECT_FALSE(manager_->CanMount("/media/removable/"));
  EXPECT_FALSE(manager_->CanMount("/media/archive"));
  EXPECT_FALSE(manager_->CanMount("/media/archive/"));
  EXPECT_FALSE(manager_->CanMount("/home/chronos/user/Downloads"));
  EXPECT_FALSE(manager_->CanMount("/home/chronos/user/Downloads/"));
}

TEST_F(DiskManagerTest, EjectDevice) {
  const base::FilePath kMountPath("/media/removable/disk");
  Disk disk;

  EXPECT_CALL(platform_, Unmount).WillRepeatedly(Return(MOUNT_ERROR_NONE));

  std::unique_ptr<MountPoint> mount_point =
      std::make_unique<MountPoint>(MountPointData{kMountPath}, &platform_);
  disk.device_file = "/dev/sda";
  disk.media_type = DEVICE_MEDIA_USB;
  EXPECT_CALL(ejector_, Eject("/dev/sda")).Times(0);
  std::unique_ptr<MountPoint> wrapped_mount_point =
      manager_->MaybeWrapMountPointForEject(std::move(mount_point), disk);
  EXPECT_EQ(MOUNT_ERROR_NONE, wrapped_mount_point->Unmount());

  mount_point =
      std::make_unique<MountPoint>(MountPointData{kMountPath}, &platform_);
  disk.device_file = "/dev/sr0";
  disk.media_type = DEVICE_MEDIA_OPTICAL_DISC;
  EXPECT_CALL(ejector_, Eject("/dev/sr0")).WillOnce(Return(true));
  wrapped_mount_point =
      manager_->MaybeWrapMountPointForEject(std::move(mount_point), disk);
  EXPECT_EQ(MOUNT_ERROR_NONE, wrapped_mount_point->Unmount());

  mount_point =
      std::make_unique<MountPoint>(MountPointData{kMountPath}, &platform_);
  disk.device_file = "/dev/sr1";
  disk.media_type = DEVICE_MEDIA_DVD;
  EXPECT_CALL(ejector_, Eject("/dev/sr1")).WillOnce(Return(true));
  wrapped_mount_point =
      manager_->MaybeWrapMountPointForEject(std::move(mount_point), disk);
  EXPECT_EQ(MOUNT_ERROR_NONE, wrapped_mount_point->Unmount());
}

TEST_F(DiskManagerTest, EjectDeviceWhenUnmountFailed) {
  const base::FilePath kMountPath("/media/removable/disk");
  Disk disk;
  disk.device_file = "/dev/sr0";
  disk.media_type = DEVICE_MEDIA_OPTICAL_DISC;

  EXPECT_CALL(platform_, Unmount).WillRepeatedly(Return(MOUNT_ERROR_UNKNOWN));

  std::unique_ptr<MountPoint> mount_point =
      std::make_unique<MountPoint>(MountPointData{kMountPath}, &platform_);
  EXPECT_CALL(ejector_, Eject("/dev/sr0")).Times(0);
  std::unique_ptr<MountPoint> wrapped_mount_point =
      manager_->MaybeWrapMountPointForEject(std::move(mount_point), disk);
  EXPECT_EQ(MOUNT_ERROR_UNKNOWN, wrapped_mount_point->Unmount());
}

TEST_F(DiskManagerTest, EjectDeviceWhenExplicitlyDisabled) {
  const base::FilePath kMountPath("/media/removable/disk");
  Disk disk;
  disk.device_file = "/dev/sr0";
  disk.media_type = DEVICE_MEDIA_OPTICAL_DISC;

  EXPECT_CALL(platform_, Unmount).WillOnce(Return(MOUNT_ERROR_NONE));

  std::unique_ptr<MountPoint> mount_point =
      std::make_unique<MountPoint>(MountPointData{kMountPath}, &platform_);
  manager_->eject_device_on_unmount_ = false;
  EXPECT_CALL(ejector_, Eject("/dev/sr0")).Times(0);
  std::unique_ptr<MountPoint> wrapped_mount_point =
      manager_->MaybeWrapMountPointForEject(std::move(mount_point), disk);
  EXPECT_EQ(MOUNT_ERROR_NONE, wrapped_mount_point->Unmount());
}

TEST_F(DiskManagerTest, EjectDeviceWhenReleased) {
  const base::FilePath kMountPath("/media/removable/disk");
  Disk disk;
  disk.device_file = "/dev/sr0";
  disk.media_type = DEVICE_MEDIA_OPTICAL_DISC;

  EXPECT_CALL(platform_, Unmount).Times(0);

  std::unique_ptr<MountPoint> mount_point =
      MountPoint::CreateUnmounted({kMountPath});
  EXPECT_CALL(ejector_, Eject("/dev/sr0")).Times(0);
  std::unique_ptr<MountPoint> wrapped_mount_point =
      manager_->MaybeWrapMountPointForEject(std::move(mount_point), disk);
  EXPECT_EQ(MOUNT_ERROR_PATH_NOT_MOUNTED, wrapped_mount_point->Unmount());
}

}  // namespace cros_disks
