// Copyright 2020 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 <base/files/file_util.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>

#include "dlcservice/boot/mock_boot_device.h"
#include "dlcservice/metrics.h"
#include "dlcservice/prefs.h"
#include "dlcservice/system_state.h"
#include "dlcservice/test_utils.h"
#include "dlcservice/utils.h"

using dlcservice::metrics::InstallResult;
using testing::_;
using testing::DoAll;
using testing::ElementsAre;
using testing::Return;
using testing::SetArgPointee;

namespace dlcservice {

class DlcBaseTest : public BaseTest {
 public:
  DlcBaseTest() = default;

  std::unique_ptr<DlcBase> Install(const DlcId& id) {
    auto dlc = std::make_unique<DlcBase>(id);
    dlc->Initialize();
    EXPECT_CALL(*mock_update_engine_proxy_ptr_, SetDlcActiveValue(_, id, _, _))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
        .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
    EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
    EXPECT_CALL(*mock_metrics_,
                SendInstallResult(InstallResult::kSuccessNewInstall));
    EXPECT_TRUE(dlc->Install(&err_));
    InstallWithUpdateEngine({id});
    dlc->InstallCompleted(&err_);
    dlc->FinishInstall(/*installed_by_ue=*/true, &err_);
    return dlc;
  }

 private:
  DlcBaseTest(const DlcBaseTest&) = delete;
  DlcBaseTest& operator=(const DlcBaseTest&) = delete;
};

class DlcBaseTestRemovable : public DlcBaseTest {
 public:
  DlcBaseTestRemovable() = default;

  void SetUp() override {
    ON_CALL(*mock_boot_device_ptr_, IsRemovableDevice(_))
        .WillByDefault(Return(true));
    DlcBaseTest::SetUp();
  }

 private:
  DlcBaseTestRemovable(const DlcBaseTestRemovable&) = delete;
  DlcBaseTestRemovable& operator=(const DlcBaseTestRemovable&) = delete;
};

TEST_F(DlcBaseTest, InitializationClearsMountFile) {
  Prefs prefs(
      JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage));
  EXPECT_TRUE(prefs.Create(kDlcRootMount));
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();
  EXPECT_FALSE(prefs.Exists(kDlcRootMount));
}

TEST_F(DlcBaseTest, CreateDlc) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);

  EXPECT_TRUE(dlc.Install(&err_));

  constexpr int expected_permissions = 0755;
  int permissions;
  base::FilePath module_path = JoinPaths(content_path_, kFirstDlc, kPackage);
  base::GetPosixFilePermissions(module_path, &permissions);
  EXPECT_EQ(permissions, expected_permissions);
  base::FilePath image_a_path =
      GetDlcImagePath(content_path_, kFirstDlc, kPackage, BootSlot::Slot::A);
  base::GetPosixFilePermissions(image_a_path.DirName(), &permissions);
  EXPECT_EQ(permissions, expected_permissions);
  base::FilePath image_b_path =
      GetDlcImagePath(content_path_, kFirstDlc, kPackage, BootSlot::Slot::B);
  base::GetPosixFilePermissions(image_b_path.DirName(), &permissions);
  EXPECT_EQ(permissions, expected_permissions);

  base::FilePath dlc_prefs_path = JoinPaths(prefs_path_, "dlc", kFirstDlc);
  EXPECT_TRUE(base::PathExists(dlc_prefs_path));
  base::GetPosixFilePermissions(dlc_prefs_path, &permissions);
  EXPECT_EQ(permissions, expected_permissions);

  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
}

TEST_F(DlcBaseTest, InstallWithUECompletion) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kFirstDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessNewInstall));

  EXPECT_TRUE(dlc.Install(&err_));
  InstallWithUpdateEngine({kFirstDlc});
  // UE calls this.
  dlc.InstallCompleted(&err_);
  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);

  dlc.FinishInstall(/*installed_by_ue=*/true, &err_);
  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLED);
  EXPECT_TRUE(dlc.IsVerified());
}

TEST_F(DlcBaseTest, InstallWithoutUECompletion) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kFirstDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessNewInstall));

  EXPECT_TRUE(dlc.Install(&err_));
  InstallWithUpdateEngine({kFirstDlc});
  // UE doesn't call InstallComplete anymore. But we still verify.
  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);

  dlc.FinishInstall(/*installed_by_ue=*/true, &err_);
  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLED);
  EXPECT_TRUE(dlc.IsVerified());
}

TEST_F(DlcBaseTest, InstallWhenInstalling) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);

  // A second install should do nothing.
  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
}

TEST_F(DlcBaseTest, VerifiedOnInitialization) {
  DlcBase dlc(kSecondDlc);

  // Explicitly set |kDlcPrefVerified| here.
  std::string value;
  EXPECT_TRUE(
      base::ReadFileToString(SystemState::Get()->verification_file(), &value));
  EXPECT_TRUE(Prefs(dlc, SystemState::Get()->active_boot_slot())
                  .SetKey(kDlcPrefVerified, value));
  EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);

  dlc.Initialize();
  EXPECT_TRUE(dlc.IsVerified());
}

TEST_F(DlcBaseTest, StaleVerificationCheckOnInitialization) {
  DlcBase dlc(kSecondDlc);

  // Explicitly set |kDlcPrefVerified| here w/ stale value.
  std::string value;
  EXPECT_TRUE(
      base::ReadFileToString(SystemState::Get()->verification_file(), &value));
  EXPECT_TRUE(Prefs(dlc, SystemState::Get()->active_boot_slot())
                  .SetKey(kDlcPrefVerified, value + "make it stale"));
  EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);

  dlc.Initialize();
  EXPECT_FALSE(dlc.IsVerified());
}

TEST_F(DlcBaseTest, InstallCompleted) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  EXPECT_FALSE(dlc.IsVerified());
  EXPECT_TRUE(dlc.InstallCompleted(&err_));
  EXPECT_TRUE(dlc.IsVerified());
}

TEST_F(DlcBaseTest, UpdateCompleted) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  EXPECT_TRUE(dlc.UpdateCompleted(&err_));
  EXPECT_TRUE(Prefs(dlc, SystemState::Get()->inactive_boot_slot())
                  .Exists(kDlcPrefVerified));
}

TEST_F(DlcBaseTest, MakeReadyForUpdate) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();
  dlc.MarkVerified();
  // Make sure the function recreates the inactive image.
  auto inactive_image_path =
      dlc.GetImagePath(SystemState::Get()->inactive_boot_slot());
  base::DeleteFile(inactive_image_path);
  EXPECT_FALSE(base::PathExists(inactive_image_path));

  Prefs prefs(dlc, SystemState::Get()->inactive_boot_slot());
  EXPECT_TRUE(prefs.Create(kDlcPrefVerified));
  EXPECT_TRUE(dlc.MakeReadyForUpdate());
  EXPECT_TRUE(base::PathExists(inactive_image_path));
  EXPECT_FALSE(prefs.Exists(kDlcPrefVerified));
}

TEST_F(DlcBaseTest, MakeReadyForUpdateNotVerfied) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  Prefs prefs(dlc, SystemState::Get()->inactive_boot_slot());
  EXPECT_TRUE(prefs.Create(kDlcPrefVerified));
  // Since DLC is not verfied, it should return false.
  EXPECT_FALSE(dlc.MakeReadyForUpdate());
  EXPECT_FALSE(prefs.Exists(kDlcPrefVerified));
}

TEST_F(DlcBaseTest, OfficialBuildsDoNotPreloadDLCs) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();
  // Place preloaded images.
  base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kThirdDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
  EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
      .WillOnce(Return(true));

  EXPECT_TRUE(dlc.Install(&err_));

  // Instead of being preloaded, it should start installing.
  EXPECT_TRUE(dlc.IsInstalling());
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTest, BootingFromNonRemovableDeviceKeepsPreloadedDLCs) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();
  // Place preloaded images.
  base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kThirdDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
  EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
      .WillOnce(Return(false));

  EXPECT_TRUE(dlc.Install(&err_));

  // Preloaded DLC image should still exists.
  EXPECT_TRUE(base::PathExists(image_path));
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTestRemovable, BootingFromRemovableDeviceKeepsPreloadedDLCs) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();
  // Place preloaded images.
  base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kThirdDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
  EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
      .WillOnce(Return(false));

  EXPECT_TRUE(dlc.Install(&err_));

  // Preloaded DLC image should still exists.
  EXPECT_TRUE(base::PathExists(image_path));
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTest, PreloadCopyShouldMarkUnverified) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();
  SetUpDlcPreloadedImage(kThirdDlc);

  // Don't preload the image so we can simulate a preload failure.
  EXPECT_TRUE(dlc.MarkVerified());
  EXPECT_FALSE(dlc.PreloadedCopier(&err_));
  EXPECT_FALSE(dlc.IsVerified());
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTest, PreloadCopyFailOnInvalidFileSize) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();
  base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
  EXPECT_TRUE(ResizeFile(image_path, 10));

  EXPECT_TRUE(dlc.MarkVerified());
  EXPECT_FALSE(dlc.PreloadedCopier(&err_));
  // This failure should not render the image as unverified.
  EXPECT_TRUE(dlc.IsVerified());
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTest, InstallingCorruptPreloadedImageCleansUp) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();
  base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
  EXPECT_TRUE(ResizeFile(image_path, 10));

  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
      .WillOnce(Return(false));

  EXPECT_FALSE(dlc.Install(&err_));
  for (const auto& path : {dlc.GetImagePath(BootSlot::Slot::A),
                           dlc.GetImagePath(BootSlot::Slot::B)})
    EXPECT_FALSE(base::PathExists(path));
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTest, PreloadingSkippedOnAlreadyVerifiedDlc) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();

  // Cause |PreloadedCopier()| to fail due to size mismatch in manifest if it
  // were to be called.
  EXPECT_TRUE(ResizeFile(SetUpDlcPreloadedImage(kThirdDlc), 1));
  SetUpDlcWithSlots(kThirdDlc);
  InstallWithUpdateEngine({kThirdDlc});

  EXPECT_TRUE(dlc.MarkVerified());
  EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_,
              LoadDlcImage(kThirdDlc, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kThirdDlc, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(dlc.IsInstalled());
}

// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
TEST_F(DlcBaseTest, PreloadingSkippedOnAlreadyExistingAndVerifiableDlc) {
  DlcBase dlc(kThirdDlc);
  dlc.Initialize();

  // Cause |PreloadedCopier()| to fail due to size mismatch in manifest if it
  // were to be called.
  EXPECT_TRUE(ResizeFile(SetUpDlcPreloadedImage(kThirdDlc), 1));
  SetUpDlcWithSlots(kThirdDlc);
  InstallWithUpdateEngine({kThirdDlc});

  EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_,
              LoadDlcImage(kThirdDlc, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kThirdDlc, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(dlc.IsInstalled());
}

TEST_F(DlcBaseTest, HasContent) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  EXPECT_FALSE(dlc.HasContent());

  SetUpDlcWithSlots(kSecondDlc);
  EXPECT_TRUE(dlc.HasContent());
}

TEST_F(DlcBaseTest, GetUsedBytesOnDisk) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  EXPECT_EQ(dlc.GetUsedBytesOnDisk(), 0);

  SetUpDlcWithSlots(kSecondDlc);
  uint64_t expected_size = 0;
  for (const auto& path : {dlc.GetImagePath(BootSlot::Slot::A),
                           dlc.GetImagePath(BootSlot::Slot::B)}) {
    expected_size += GetFileSize(path);
  }
  EXPECT_GT(expected_size, 0);

  EXPECT_EQ(dlc.GetUsedBytesOnDisk(), expected_size);
}

TEST_F(DlcBaseTest, MarkVerified) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_FALSE(dlc.IsVerified());
  EXPECT_TRUE(dlc.MarkVerified());
  EXPECT_TRUE(dlc.IsVerified());
  EXPECT_TRUE(Prefs(DlcBase(kFirstDlc), SystemState::Get()->active_boot_slot())
                  .Exists(kDlcPrefVerified));
}

TEST_F(DlcBaseTest, MarkUnverified) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_TRUE(dlc.MarkVerified());
  EXPECT_TRUE(dlc.MarkUnverified());
  EXPECT_FALSE(dlc.IsVerified());
  EXPECT_FALSE(Prefs(DlcBase(kFirstDlc), SystemState::Get()->active_boot_slot())
                   .Exists(kDlcPrefVerified));
}

TEST_F(DlcBaseTest, ImageOnDiskButNotVerifiedInstalls) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  SetUpDlcWithSlots(kSecondDlc);
  InstallWithUpdateEngine({kSecondDlc});

  EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_,
              LoadDlcImage(kSecondDlc, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kSecondDlc, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(dlc.IsInstalled());
}

TEST_F(DlcBaseTest, ImageOnDiskVerifiedInstalls) {
  DlcBase dlc(kSecondDlc);
  EXPECT_TRUE(Prefs(dlc, SystemState::Get()->active_boot_slot())
                  .Create(kDlcPrefVerified));
  SetUpDlcWithSlots(kSecondDlc);
  InstallWithUpdateEngine({kSecondDlc});

  dlc.Initialize();

  EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_,
              LoadDlcImage(kSecondDlc, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kSecondDlc, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(dlc.IsInstalled());
}

TEST_F(DlcBaseTest, VerifyDlcImageOnUEFailureToCompleteInstall) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kSecondDlc, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(*mock_image_loader_proxy_ptr_,
              LoadDlcImage(kSecondDlc, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessNewInstall));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(dlc.IsInstalling());

  // Intentionally skip over setting verified mark before |FinishInstall()|.
  InstallWithUpdateEngine({kSecondDlc});

  EXPECT_TRUE(dlc.FinishInstall(/*installed_by_ue=*/true, &err_));
  EXPECT_TRUE(dlc.IsInstalled());
}

TEST_F(DlcBaseTest, NoImageFoundOnUEFailureToDownloadDlc) {
  DlcBase dlc(kSecondDlc);
  dlc.Initialize();

  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kFailedNoImageFound));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(dlc.IsInstalling());

  // Make sure the `last_attempt_error` in update_engine is set to `kNoUpdate`.
  update_engine::StatusResult ue_status;
  ue_status.set_last_attempt_error(
      static_cast<int32_t>(update_engine::ErrorCode::kNoUpdate));
  SystemState::Get()->set_update_engine_status(ue_status);

  EXPECT_FALSE(dlc.FinishInstall(/*installed_by_ue=*/true, &err_));
}

TEST_F(DlcBaseTest, DefaultState) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();
  dlc.mount_point_ = base::FilePath("foo-path");

  DlcState state = dlc.GetState();
  EXPECT_EQ(state.id(), kFirstDlc);
  EXPECT_EQ(state.state(), DlcState::NOT_INSTALLED);
  EXPECT_EQ(state.progress(), 0);
  EXPECT_EQ(state.root_path(), "");
}

TEST_F(DlcBaseTest, ChangeStateNotInstalled) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();
  dlc.mount_point_ = base::FilePath("foo-path");

  EXPECT_CALL(
      mock_state_change_reporter_,
      DlcStateChanged(CheckDlcStateProto(DlcState::NOT_INSTALLED, 0, "")));
  dlc.ChangeState(DlcState::NOT_INSTALLED);
}

TEST_F(DlcBaseTest, ChangeStateInstalling) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();
  dlc.mount_point_ = base::FilePath("foo-path");

  EXPECT_CALL(mock_state_change_reporter_,
              DlcStateChanged(CheckDlcStateProto(DlcState::INSTALLING, 0, "")));
  dlc.ChangeState(DlcState::INSTALLING);
}

TEST_F(DlcBaseTest, ChangeStateInstalled) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();
  dlc.mount_point_ = base::FilePath("foo-path");

  // The |root_path| in |DlcState| should point to the root of the mount point.
  EXPECT_CALL(mock_state_change_reporter_,
              DlcStateChanged(CheckDlcStateProto(DlcState::INSTALLED, 1.0,
                                                 "foo-path/root")));
  dlc.ChangeState(DlcState::INSTALLED);
}

TEST_F(DlcBaseTest, ChangeProgress) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  // Any state other than installing should not change the progress.
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(0);
  dlc.ChangeProgress(0.5);

  EXPECT_CALL(mock_state_change_reporter_,
              DlcStateChanged(CheckDlcStateProto(DlcState::INSTALLING, 0, "")));
  dlc.ChangeState(DlcState::INSTALLING);

  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(CheckDlcStateProto(
                                               DlcState::INSTALLING, 0.5, "")));
  dlc.ChangeProgress(0.5);

  // Lower progress should not send signal.
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(0);
  dlc.ChangeProgress(0.3);

  // Same progress should not send the signal.
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(0);
  dlc.ChangeProgress(0.5);
}

TEST_F(DlcBaseTest, InstallIncreasesRefCount) {
  DlcBase dlc(kFirstDlc);
  dlc.Initialize();

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kFirstDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessNewInstall));

  EXPECT_TRUE(dlc.Install(&err_));
  InstallWithUpdateEngine({kFirstDlc});
  dlc.InstallCompleted(&err_);
  dlc.FinishInstall(/*installed_by_ue=*/true, &err_);

  EXPECT_TRUE(dlc.IsInstalled());
  auto ref_count_file = JoinPaths(SystemState::Get()->dlc_prefs_dir(),
                                  kFirstDlc, kRefCountFileName);
  EXPECT_TRUE(base::PathExists(ref_count_file));
}

TEST_F(DlcBaseTest, MountFileCreated) {
  // |kFirstDlc| has 'mount-file-required' as true in the manifest.
  DlcBase dlc(kFirstDlc);
  SetUpDlcWithSlots(kFirstDlc);
  InstallWithUpdateEngine({kFirstDlc});
  dlc.Initialize();

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kFirstDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_TRUE(
      Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage))
          .Exists(kDlcRootMount));
}

TEST_F(DlcBaseTest, MountFileNotCreated) {
  // |kSecondDlc| has 'mount-file-required' as false in the manifest.
  DlcBase dlc(kSecondDlc);
  SetUpDlcWithSlots(kSecondDlc);
  InstallWithUpdateEngine({kSecondDlc});
  dlc.Initialize();

  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kSecondDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));

  EXPECT_TRUE(dlc.Install(&err_));
  EXPECT_FALSE(Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kSecondDlc,
                               kPackage))
                   .Exists(kDlcRootMount));
}

TEST_F(DlcBaseTest, MountFileRequiredDeletionOnUninstall) {
  DlcBase dlc(kFirstDlc);
  SetUpDlcWithSlots(kFirstDlc);
  InstallWithUpdateEngine({kFirstDlc});
  dlc.Initialize();

  // Process |Install()|.
  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kFirstDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
  EXPECT_TRUE(dlc.Install(&err_));

  // Process |Uninstall()| + check.
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, UnloadDlcImage(_, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<2>(true), Return(true)));
  EXPECT_TRUE(dlc.Uninstall(&err_));
  EXPECT_FALSE(
      Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage))
          .Exists(kDlcRootMount));
}

TEST_F(DlcBaseTest, MountFileRequiredDeletionOnPurge) {
  DlcBase dlc(kFirstDlc);
  SetUpDlcWithSlots(kFirstDlc);
  InstallWithUpdateEngine({kFirstDlc});
  dlc.Initialize();

  // Process |Install()|.
  EXPECT_CALL(*mock_update_engine_proxy_ptr_,
              SetDlcActiveValue(_, kFirstDlc, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
  EXPECT_CALL(*mock_metrics_,
              SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
  EXPECT_TRUE(dlc.Install(&err_));

  // Process |Purge()| + check.
  EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
  EXPECT_CALL(*mock_image_loader_proxy_ptr_, UnloadDlcImage(_, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<2>(true), Return(true)));
  EXPECT_TRUE(dlc.Purge(&err_));
  EXPECT_FALSE(
      Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage))
          .Exists(kDlcRootMount));
}

TEST_F(DlcBaseTest, UnmountClearsMountPoint) {
  auto dlc = Install(kFirstDlc);

  EXPECT_CALL(*mock_image_loader_proxy_ptr_, UnloadDlcImage(_, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<2>(true), Return(true)));
  EXPECT_TRUE(dlc->Unmount(&err_));
  EXPECT_TRUE(dlc->GetRoot().empty());
}

}  // namespace dlcservice
