//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/update_attempter.h"

#include <stdint.h>

#include <memory>
#include <unordered_set>

#include <base/files/file_util.h>
#include <base/message_loop/message_loop.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop.h>
#include <brillo/message_loops/message_loop_utils.h>
#include <gtest/gtest.h>
#include <policy/libpolicy.h>
#include <policy/mock_device_policy.h>
#include <policy/mock_libpolicy.h>

#include "update_engine/common/constants.h"
#include "update_engine/common/dlcservice_interface.h"
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_prefs.h"
#include "update_engine/common/mock_action.h"
#include "update_engine/common/mock_action_processor.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/fake_system_state.h"
#include "update_engine/libcurl_http_fetcher.h"
#include "update_engine/mock_p2p_manager.h"
#include "update_engine/mock_payload_state.h"
#include "update_engine/mock_service_observer.h"
#include "update_engine/payload_consumer/filesystem_verifier_action.h"
#include "update_engine/payload_consumer/install_plan.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_consumer/postinstall_runner_action.h"
#include "update_engine/update_boot_flags_action.h"
#include "update_engine/update_manager/mock_update_manager.h"

using base::Time;
using base::TimeDelta;
using chromeos_update_manager::EvalStatus;
using chromeos_update_manager::MockUpdateManager;
using chromeos_update_manager::StagingSchedule;
using chromeos_update_manager::UpdateCheckParams;
using policy::DevicePolicy;
using std::string;
using std::unique_ptr;
using std::unordered_set;
using std::vector;
using testing::_;
using testing::DoAll;
using testing::Field;
using testing::InSequence;
using testing::Invoke;
using testing::Ne;
using testing::NiceMock;
using testing::Pointee;
using testing::Property;
using testing::Return;
using testing::ReturnPointee;
using testing::ReturnRef;
using testing::SaveArg;
using testing::SetArgPointee;
using update_engine::UpdateAttemptFlags;
using update_engine::UpdateEngineStatus;
using update_engine::UpdateStatus;

namespace chromeos_update_engine {

namespace {

const UpdateStatus kNonIdleUpdateStatuses[] = {
    UpdateStatus::CHECKING_FOR_UPDATE,
    UpdateStatus::UPDATE_AVAILABLE,
    UpdateStatus::DOWNLOADING,
    UpdateStatus::VERIFYING,
    UpdateStatus::FINALIZING,
    UpdateStatus::UPDATED_NEED_REBOOT,
    UpdateStatus::REPORTING_ERROR_EVENT,
    UpdateStatus::ATTEMPTING_ROLLBACK,
    UpdateStatus::DISABLED,
    UpdateStatus::NEED_PERMISSION_TO_UPDATE,
};

struct CheckForUpdateTestParams {
  // Setups + Inputs:
  UpdateStatus status = UpdateStatus::IDLE;
  string app_version = "fake_app_version";
  string omaha_url = "fake_omaha_url";
  UpdateAttemptFlags flags = UpdateAttemptFlags::kNone;
  bool is_official_build = true;
  bool are_dev_features_enabled = false;

  // Expects:
  string expected_forced_app_version = "";
  string expected_forced_omaha_url = "";
  bool should_schedule_updates_be_called = true;
  bool expected_result = true;
};

struct OnUpdateScheduledTestParams {
  // Setups + Inputs:
  UpdateCheckParams params = {};
  EvalStatus status = EvalStatus::kFailed;
  // Expects:
  UpdateStatus exit_status = UpdateStatus::IDLE;
  bool should_schedule_updates_be_called = false;
  bool should_update_be_called = false;
};

class MockDlcService : public DlcServiceInterface {
 public:
  MOCK_METHOD1(GetInstalled, bool(vector<string>*));
};

}  // namespace

const char kRollbackVersion[] = "10575.39.2";

// Test a subclass rather than the main class directly so that we can mock out
// methods within the class. There're explicit unit tests for the mocked out
// methods.
class UpdateAttempterUnderTest : public UpdateAttempter {
 public:
  explicit UpdateAttempterUnderTest(SystemState* system_state)
      : UpdateAttempter(system_state, nullptr) {}

  void Update(const std::string& app_version,
              const std::string& omaha_url,
              const std::string& target_channel,
              const std::string& target_version_prefix,
              bool rollback_allowed,
              bool rollback_data_save_requested,
              int rollback_allowed_milestones,
              bool obey_proxies,
              bool interactive) override {
    update_called_ = true;
    if (do_update_) {
      UpdateAttempter::Update(app_version,
                              omaha_url,
                              target_channel,
                              target_version_prefix,
                              rollback_allowed,
                              rollback_data_save_requested,
                              rollback_allowed_milestones,
                              obey_proxies,
                              interactive);
      return;
    }
    LOG(INFO) << "[TEST] Update() disabled.";
    status_ = UpdateStatus::CHECKING_FOR_UPDATE;
  }

  void DisableUpdate() { do_update_ = false; }

  bool WasUpdateCalled() const { return update_called_; }

  // Wrap the update scheduling method, allowing us to opt out of scheduled
  // updates for testing purposes.
  bool ScheduleUpdates() override {
    schedule_updates_called_ = true;
    if (do_schedule_updates_)
      return UpdateAttempter::ScheduleUpdates();
    LOG(INFO) << "[TEST] Update scheduling disabled.";
    waiting_for_scheduled_check_ = true;
    return true;
  }

  void DisableScheduleUpdates() { do_schedule_updates_ = false; }

  // Indicates whether |ScheduleUpdates()| was called.
  bool WasScheduleUpdatesCalled() const { return schedule_updates_called_; }

  // Need to expose following private members of |UpdateAttempter| for tests.
  const string& forced_app_version() const { return forced_app_version_; }
  const string& forced_omaha_url() const { return forced_omaha_url_; }

  // Need to expose |waiting_for_scheduled_check_| for testing.
  void SetWaitingForScheduledCheck(bool waiting) {
    waiting_for_scheduled_check_ = waiting;
  }

 private:
  // Used for overrides of |Update()|.
  bool update_called_ = false;
  bool do_update_ = true;

  // Used for overrides of |ScheduleUpdates()|.
  bool schedule_updates_called_ = false;
  bool do_schedule_updates_ = true;
};

class UpdateAttempterTest : public ::testing::Test {
 protected:
  UpdateAttempterTest()
      : certificate_checker_(fake_system_state_.mock_prefs(),
                             &openssl_wrapper_) {
    // Override system state members.
    fake_system_state_.set_connection_manager(&mock_connection_manager);
    fake_system_state_.set_update_attempter(&attempter_);
    fake_system_state_.set_dlcservice(&mock_dlcservice_);
    fake_system_state_.set_update_manager(&mock_update_manager_);
    loop_.SetAsCurrent();

    certificate_checker_.Init();

    attempter_.set_forced_update_pending_callback(
        new base::Callback<void(bool, bool)>(base::Bind([](bool, bool) {})));
    // Finish initializing the attempter.
    attempter_.Init();
  }

  void SetUp() override {
    EXPECT_NE(nullptr, attempter_.system_state_);
    EXPECT_NE(nullptr, attempter_.system_state_->update_manager());
    EXPECT_EQ(0, attempter_.http_response_code_);
    EXPECT_EQ(UpdateStatus::IDLE, attempter_.status_);
    EXPECT_EQ(0.0, attempter_.download_progress_);
    EXPECT_EQ(0, attempter_.last_checked_time_);
    EXPECT_EQ("0.0.0.0", attempter_.new_version_);
    EXPECT_EQ(0ULL, attempter_.new_payload_size_);
    processor_ = new NiceMock<MockActionProcessor>();
    attempter_.processor_.reset(processor_);  // Transfers ownership.
    prefs_ = fake_system_state_.mock_prefs();

    // Setup store/load semantics of P2P properties via the mock |PayloadState|.
    actual_using_p2p_for_downloading_ = false;
    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
                SetUsingP2PForDownloading(_))
        .WillRepeatedly(SaveArg<0>(&actual_using_p2p_for_downloading_));
    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
                GetUsingP2PForDownloading())
        .WillRepeatedly(ReturnPointee(&actual_using_p2p_for_downloading_));
    actual_using_p2p_for_sharing_ = false;
    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
                SetUsingP2PForSharing(_))
        .WillRepeatedly(SaveArg<0>(&actual_using_p2p_for_sharing_));
    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
                GetUsingP2PForDownloading())
        .WillRepeatedly(ReturnPointee(&actual_using_p2p_for_sharing_));
  }

 public:
  void ScheduleQuitMainLoop();

  // Callbacks to run the different tests from the main loop.
  void UpdateTestStart();
  void UpdateTestVerify();
  void RollbackTestStart(bool enterprise_rollback, bool valid_slot);
  void RollbackTestVerify();
  void PingOmahaTestStart();
  void ReadScatterFactorFromPolicyTestStart();
  void DecrementUpdateCheckCountTestStart();
  void NoScatteringDoneDuringManualUpdateTestStart();
  void P2PNotEnabledStart();
  void P2PEnabledStart();
  void P2PEnabledInteractiveStart();
  void P2PEnabledStartingFailsStart();
  void P2PEnabledHousekeepingFailsStart();
  void SessionIdTestChange();
  void SessionIdTestEnforceEmptyStrPingOmaha();
  void SessionIdTestConsistencyInUpdateFlow();
  void SessionIdTestInDownloadAction();
  void UpdateToQuickFixBuildStart(bool set_token);
  void ResetRollbackHappenedStart(bool is_consumer,
                                  bool is_policy_available,
                                  bool expected_reset);
  // Staging related callbacks.
  void SetUpStagingTest(const StagingSchedule& schedule, FakePrefs* prefs);
  void CheckStagingOff();
  void StagingSetsPrefsAndTurnsOffScatteringStart();
  void StagingOffIfInteractiveStart();
  void StagingOffIfOobeStart();

  bool actual_using_p2p_for_downloading() {
    return actual_using_p2p_for_downloading_;
  }
  bool actual_using_p2p_for_sharing() { return actual_using_p2p_for_sharing_; }

  // |CheckForUpdate()| related member functions.
  void TestCheckForUpdate();

  // |OnUpdateScheduled()| related member functions.
  void TestOnUpdateScheduled();

  base::MessageLoopForIO base_loop_;
  brillo::BaseMessageLoop loop_{&base_loop_};

  FakeSystemState fake_system_state_;
  UpdateAttempterUnderTest attempter_{&fake_system_state_};
  OpenSSLWrapper openssl_wrapper_;
  CertificateChecker certificate_checker_;
  MockDlcService mock_dlcservice_;
  MockUpdateManager mock_update_manager_;

  NiceMock<MockActionProcessor>* processor_;
  NiceMock<MockPrefs>*
      prefs_;  // Shortcut to |fake_system_state_->mock_prefs()|.
  NiceMock<MockConnectionManager> mock_connection_manager;

  // |CheckForUpdate()| test params.
  CheckForUpdateTestParams cfu_params_;

  // |OnUpdateScheduled()| test params.
  OnUpdateScheduledTestParams ous_params_;

  bool actual_using_p2p_for_downloading_;
  bool actual_using_p2p_for_sharing_;
};

void UpdateAttempterTest::TestCheckForUpdate() {
  // Setup
  attempter_.status_ = cfu_params_.status;
  fake_system_state_.fake_hardware()->SetIsOfficialBuild(
      cfu_params_.is_official_build);
  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(
      cfu_params_.are_dev_features_enabled);

  // Invocation
  EXPECT_EQ(
      cfu_params_.expected_result,
      attempter_.CheckForUpdate(
          cfu_params_.app_version, cfu_params_.omaha_url, cfu_params_.flags));

  // Verify
  EXPECT_EQ(cfu_params_.expected_forced_app_version,
            attempter_.forced_app_version());
  EXPECT_EQ(cfu_params_.expected_forced_omaha_url,
            attempter_.forced_omaha_url());
  EXPECT_EQ(cfu_params_.should_schedule_updates_be_called,
            attempter_.WasScheduleUpdatesCalled());
}

void UpdateAttempterTest::ScheduleQuitMainLoop() {
  loop_.PostTask(
      FROM_HERE,
      base::Bind([](brillo::BaseMessageLoop* loop) { loop->BreakLoop(); },
                 base::Unretained(&loop_)));
}

void UpdateAttempterTest::SessionIdTestChange() {
  EXPECT_NE(UpdateStatus::UPDATED_NEED_REBOOT, attempter_.status());
  const auto old_session_id = attempter_.session_id_;
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_NE(old_session_id, attempter_.session_id_);
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, SessionIdTestChange) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::SessionIdTestChange,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::SessionIdTestEnforceEmptyStrPingOmaha() {
  // The |session_id_| should not be changed and should remain as an empty
  // string when |status_| is |UPDATED_NEED_REBOOT| (only for consistency)
  // and |PingOmaha()| is called.
  attempter_.DisableScheduleUpdates();
  attempter_.status_ = UpdateStatus::UPDATED_NEED_REBOOT;
  const auto old_session_id = attempter_.session_id_;
  auto CheckIfEmptySessionId = [](AbstractAction* aa) {
    if (aa->Type() == OmahaRequestAction::StaticType()) {
      EXPECT_TRUE(static_cast<OmahaRequestAction*>(aa)->session_id_.empty());
    }
  };
  EXPECT_CALL(*processor_, EnqueueAction(Pointee(_)))
      .WillRepeatedly(Invoke(CheckIfEmptySessionId));
  EXPECT_CALL(*processor_, StartProcessing());
  attempter_.PingOmaha();
  EXPECT_EQ(old_session_id, attempter_.session_id_);
  EXPECT_EQ(UpdateStatus::UPDATED_NEED_REBOOT, attempter_.status_);
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, SessionIdTestEnforceEmptyStrPingOmaha) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(&UpdateAttempterTest::SessionIdTestEnforceEmptyStrPingOmaha,
                 base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::SessionIdTestConsistencyInUpdateFlow() {
  // All session IDs passed into |OmahaRequestActions| should be enforced to
  // have the same value in |BuildUpdateActions()|.
  unordered_set<string> session_ids;
  // Gather all the session IDs being passed to |OmahaRequestActions|.
  auto CheckSessionId = [&session_ids](AbstractAction* aa) {
    if (aa->Type() == OmahaRequestAction::StaticType())
      session_ids.insert(static_cast<OmahaRequestAction*>(aa)->session_id_);
  };
  EXPECT_CALL(*processor_, EnqueueAction(Pointee(_)))
      .WillRepeatedly(Invoke(CheckSessionId));
  attempter_.BuildUpdateActions(false);
  // Validate that all the session IDs are the same.
  EXPECT_EQ(1, session_ids.size());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, SessionIdTestConsistencyInUpdateFlow) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(&UpdateAttempterTest::SessionIdTestConsistencyInUpdateFlow,
                 base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::SessionIdTestInDownloadAction() {
  // The session ID passed into |DownloadAction|'s |LibcurlHttpFetcher| should
  // be enforced to be included in the HTTP header as X-Goog-Update-SessionId.
  string header_value;
  auto CheckSessionIdInDownloadAction = [&header_value](AbstractAction* aa) {
    if (aa->Type() == DownloadAction::StaticType()) {
      DownloadAction* da = static_cast<DownloadAction*>(aa);
      EXPECT_TRUE(da->http_fetcher()->GetHeader(kXGoogleUpdateSessionId,
                                                &header_value));
    }
  };
  EXPECT_CALL(*processor_, EnqueueAction(Pointee(_)))
      .WillRepeatedly(Invoke(CheckSessionIdInDownloadAction));
  attempter_.BuildUpdateActions(false);
  // Validate that X-Goog-Update_SessionId is set correctly in HTTP Header.
  EXPECT_EQ(attempter_.session_id_, header_value);
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, SessionIdTestInDownloadAction) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::SessionIdTestInDownloadAction,
                            base::Unretained(this)));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, ActionCompletedDownloadTest) {
  unique_ptr<MockHttpFetcher> fetcher(new MockHttpFetcher("", 0, nullptr));
  fetcher->FailTransfer(503);  // Sets the HTTP response code.
  DownloadAction action(prefs_,
                        nullptr,
                        nullptr,
                        nullptr,
                        fetcher.release(),
                        false /* interactive */);
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _)).Times(0);
  attempter_.ActionCompleted(nullptr, &action, ErrorCode::kSuccess);
  EXPECT_EQ(UpdateStatus::FINALIZING, attempter_.status());
  EXPECT_EQ(0.0, attempter_.download_progress_);
  ASSERT_EQ(nullptr, attempter_.error_event_.get());
}

TEST_F(UpdateAttempterTest, ActionCompletedErrorTest) {
  MockAction action;
  EXPECT_CALL(action, Type()).WillRepeatedly(Return("MockAction"));
  attempter_.status_ = UpdateStatus::DOWNLOADING;
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
      .WillOnce(Return(false));
  attempter_.ActionCompleted(nullptr, &action, ErrorCode::kError);
  ASSERT_NE(nullptr, attempter_.error_event_.get());
}

TEST_F(UpdateAttempterTest, DownloadProgressAccumulationTest) {
  // Simple test case, where all the values match (nothing was skipped)
  uint64_t bytes_progressed_1 = 1024 * 1024;  // 1MB
  uint64_t bytes_progressed_2 = 1024 * 1024;  // 1MB
  uint64_t bytes_received_1 = bytes_progressed_1;
  uint64_t bytes_received_2 = bytes_received_1 + bytes_progressed_2;
  uint64_t bytes_total = 20 * 1024 * 1024;  // 20MB

  double progress_1 =
      static_cast<double>(bytes_received_1) / static_cast<double>(bytes_total);
  double progress_2 =
      static_cast<double>(bytes_received_2) / static_cast<double>(bytes_total);

  EXPECT_EQ(0.0, attempter_.download_progress_);
  // This is set via inspecting the InstallPlan payloads when the
  // |OmahaResponseAction| is completed.
  attempter_.new_payload_size_ = bytes_total;
  NiceMock<MockServiceObserver> observer;
  EXPECT_CALL(observer,
              SendStatusUpdate(AllOf(
                  Field(&UpdateEngineStatus::progress, progress_1),
                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
  EXPECT_CALL(observer,
              SendStatusUpdate(AllOf(
                  Field(&UpdateEngineStatus::progress, progress_2),
                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
  attempter_.AddObserver(&observer);
  attempter_.BytesReceived(bytes_progressed_1, bytes_received_1, bytes_total);
  EXPECT_EQ(progress_1, attempter_.download_progress_);
  // This iteration validates that a later set of updates to the variables are
  // properly handled (so that |getStatus()| will return the same progress info
  // as the callback is receiving.
  attempter_.BytesReceived(bytes_progressed_2, bytes_received_2, bytes_total);
  EXPECT_EQ(progress_2, attempter_.download_progress_);
}

TEST_F(UpdateAttempterTest, ChangeToDownloadingOnReceivedBytesTest) {
  // The transition into |UpdateStatus::DOWNLOADING| happens when the
  // first bytes are received.
  uint64_t bytes_progressed = 1024 * 1024;    // 1MB
  uint64_t bytes_received = 2 * 1024 * 1024;  // 2MB
  uint64_t bytes_total = 20 * 1024 * 1024;    // 300MB
  attempter_.status_ = UpdateStatus::CHECKING_FOR_UPDATE;
  // This is set via inspecting the InstallPlan payloads when the
  // |OmahaResponseAction| is completed.
  attempter_.new_payload_size_ = bytes_total;
  EXPECT_EQ(0.0, attempter_.download_progress_);
  NiceMock<MockServiceObserver> observer;
  EXPECT_CALL(observer,
              SendStatusUpdate(AllOf(
                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
  attempter_.AddObserver(&observer);
  attempter_.BytesReceived(bytes_progressed, bytes_received, bytes_total);
  EXPECT_EQ(UpdateStatus::DOWNLOADING, attempter_.status_);
}

TEST_F(UpdateAttempterTest, BroadcastCompleteDownloadTest) {
  // There is a special case to ensure that at 100% downloaded,
  // |download_progress_| is updated and broadcastest.
  uint64_t bytes_progressed = 0;              // ignored
  uint64_t bytes_received = 5 * 1024 * 1024;  // ignored
  uint64_t bytes_total = 5 * 1024 * 1024;     // 300MB
  attempter_.status_ = UpdateStatus::DOWNLOADING;
  attempter_.new_payload_size_ = bytes_total;
  EXPECT_EQ(0.0, attempter_.download_progress_);
  NiceMock<MockServiceObserver> observer;
  EXPECT_CALL(observer,
              SendStatusUpdate(AllOf(
                  Field(&UpdateEngineStatus::progress, 1.0),
                  Field(&UpdateEngineStatus::status, UpdateStatus::DOWNLOADING),
                  Field(&UpdateEngineStatus::new_size_bytes, bytes_total))));
  attempter_.AddObserver(&observer);
  attempter_.BytesReceived(bytes_progressed, bytes_received, bytes_total);
  EXPECT_EQ(1.0, attempter_.download_progress_);
}

TEST_F(UpdateAttempterTest, ActionCompletedOmahaRequestTest) {
  unique_ptr<MockHttpFetcher> fetcher(new MockHttpFetcher("", 0, nullptr));
  fetcher->FailTransfer(500);  // Sets the HTTP response code.
  OmahaRequestAction action(
      &fake_system_state_, nullptr, std::move(fetcher), false, "");
  ObjectCollectorAction<OmahaResponse> collector_action;
  BondActions(&action, &collector_action);
  OmahaResponse response;
  response.poll_interval = 234;
  action.SetOutputObject(response);
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _)).Times(0);
  attempter_.ActionCompleted(nullptr, &action, ErrorCode::kSuccess);
  EXPECT_EQ(500, attempter_.http_response_code());
  EXPECT_EQ(UpdateStatus::IDLE, attempter_.status());
  EXPECT_EQ(234U, attempter_.server_dictated_poll_interval_);
  ASSERT_TRUE(attempter_.error_event_.get() == nullptr);
}

TEST_F(UpdateAttempterTest, ConstructWithUpdatedMarkerTest) {
  FakePrefs fake_prefs;
  string boot_id;
  EXPECT_TRUE(utils::GetBootId(&boot_id));
  fake_prefs.SetString(kPrefsUpdateCompletedOnBootId, boot_id);
  fake_system_state_.set_prefs(&fake_prefs);
  attempter_.Init();
  EXPECT_EQ(UpdateStatus::UPDATED_NEED_REBOOT, attempter_.status());
}

TEST_F(UpdateAttempterTest, GetErrorCodeForActionTest) {
  EXPECT_EQ(ErrorCode::kSuccess,
            GetErrorCodeForAction(nullptr, ErrorCode::kSuccess));

  FakeSystemState fake_system_state;
  OmahaRequestAction omaha_request_action(
      &fake_system_state, nullptr, nullptr, false, "");
  EXPECT_EQ(ErrorCode::kOmahaRequestError,
            GetErrorCodeForAction(&omaha_request_action, ErrorCode::kError));
  OmahaResponseHandlerAction omaha_response_handler_action(&fake_system_state_);
  EXPECT_EQ(
      ErrorCode::kOmahaResponseHandlerError,
      GetErrorCodeForAction(&omaha_response_handler_action, ErrorCode::kError));
  FilesystemVerifierAction filesystem_verifier_action;
  EXPECT_EQ(
      ErrorCode::kFilesystemVerifierError,
      GetErrorCodeForAction(&filesystem_verifier_action, ErrorCode::kError));
  PostinstallRunnerAction postinstall_runner_action(
      fake_system_state.fake_boot_control(), fake_system_state.fake_hardware());
  EXPECT_EQ(
      ErrorCode::kPostinstallRunnerError,
      GetErrorCodeForAction(&postinstall_runner_action, ErrorCode::kError));
  MockAction action_mock;
  EXPECT_CALL(action_mock, Type()).WillOnce(Return("MockAction"));
  EXPECT_EQ(ErrorCode::kError,
            GetErrorCodeForAction(&action_mock, ErrorCode::kError));
}

TEST_F(UpdateAttempterTest, DisableDeltaUpdateIfNeededTest) {
  attempter_.omaha_request_params_->set_delta_okay(true);
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
      .WillOnce(Return(false));
  attempter_.DisableDeltaUpdateIfNeeded();
  EXPECT_TRUE(attempter_.omaha_request_params_->delta_okay());
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
      .WillOnce(
          DoAll(SetArgPointee<1>(UpdateAttempter::kMaxDeltaUpdateFailures - 1),
                Return(true)));
  attempter_.DisableDeltaUpdateIfNeeded();
  EXPECT_TRUE(attempter_.omaha_request_params_->delta_okay());
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
      .WillOnce(
          DoAll(SetArgPointee<1>(UpdateAttempter::kMaxDeltaUpdateFailures),
                Return(true)));
  attempter_.DisableDeltaUpdateIfNeeded();
  EXPECT_FALSE(attempter_.omaha_request_params_->delta_okay());
  EXPECT_CALL(*prefs_, GetInt64(_, _)).Times(0);
  attempter_.DisableDeltaUpdateIfNeeded();
  EXPECT_FALSE(attempter_.omaha_request_params_->delta_okay());
}

TEST_F(UpdateAttempterTest, MarkDeltaUpdateFailureTest) {
  EXPECT_CALL(*prefs_, GetInt64(kPrefsDeltaUpdateFailures, _))
      .WillOnce(Return(false))
      .WillOnce(DoAll(SetArgPointee<1>(-1), Return(true)))
      .WillOnce(DoAll(SetArgPointee<1>(1), Return(true)))
      .WillOnce(
          DoAll(SetArgPointee<1>(UpdateAttempter::kMaxDeltaUpdateFailures),
                Return(true)));
  EXPECT_CALL(*prefs_, SetInt64(Ne(kPrefsDeltaUpdateFailures), _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*prefs_, SetInt64(kPrefsDeltaUpdateFailures, 1)).Times(2);
  EXPECT_CALL(*prefs_, SetInt64(kPrefsDeltaUpdateFailures, 2));
  EXPECT_CALL(*prefs_,
              SetInt64(kPrefsDeltaUpdateFailures,
                       UpdateAttempter::kMaxDeltaUpdateFailures + 1));
  for (int i = 0; i < 4; i++)
    attempter_.MarkDeltaUpdateFailure();
}

TEST_F(UpdateAttempterTest, ScheduleErrorEventActionNoEventTest) {
  EXPECT_CALL(*processor_, EnqueueAction(_)).Times(0);
  EXPECT_CALL(*processor_, StartProcessing()).Times(0);
  EXPECT_CALL(*fake_system_state_.mock_payload_state(), UpdateFailed(_))
      .Times(0);
  OmahaResponse response;
  string url1 = "http://url1";
  response.packages.push_back({.payload_urls = {url1, "https://url"}});
  EXPECT_CALL(*(fake_system_state_.mock_payload_state()), GetCurrentUrl())
      .WillRepeatedly(Return(url1));
  fake_system_state_.mock_payload_state()->SetResponse(response);
  attempter_.ScheduleErrorEventAction();
  EXPECT_EQ(url1, fake_system_state_.mock_payload_state()->GetCurrentUrl());
}

TEST_F(UpdateAttempterTest, ScheduleErrorEventActionTest) {
  EXPECT_CALL(*processor_,
              EnqueueAction(Pointee(Property(
                  &AbstractAction::Type, OmahaRequestAction::StaticType()))));
  EXPECT_CALL(*processor_, StartProcessing());
  ErrorCode err = ErrorCode::kError;
  EXPECT_CALL(*fake_system_state_.mock_payload_state(), UpdateFailed(err));
  attempter_.error_event_.reset(new OmahaEvent(
      OmahaEvent::kTypeUpdateComplete, OmahaEvent::kResultError, err));
  attempter_.ScheduleErrorEventAction();
  EXPECT_EQ(UpdateStatus::REPORTING_ERROR_EVENT, attempter_.status());
}

namespace {
// Actions that will be built as part of an update check.
vector<string> GetUpdateActionTypes() {
  return {OmahaRequestAction::StaticType(),
          OmahaResponseHandlerAction::StaticType(),
          UpdateBootFlagsAction::StaticType(),
          OmahaRequestAction::StaticType(),
          DownloadAction::StaticType(),
          OmahaRequestAction::StaticType(),
          FilesystemVerifierAction::StaticType(),
          PostinstallRunnerAction::StaticType(),
          OmahaRequestAction::StaticType()};
}

// Actions that will be built as part of a user-initiated rollback.
vector<string> GetRollbackActionTypes() {
  return {InstallPlanAction::StaticType(),
          PostinstallRunnerAction::StaticType()};
}

const StagingSchedule kValidStagingSchedule = {
    {4, 10}, {10, 40}, {19, 70}, {26, 100}};

}  // namespace

void UpdateAttempterTest::UpdateTestStart() {
  attempter_.set_http_response_code(200);

  // Expect that the device policy is loaded by the |UpdateAttempter| at some
  // point by calling |RefreshDevicePolicy()|.
  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  EXPECT_CALL(*device_policy, LoadPolicy())
      .Times(testing::AtLeast(1))
      .WillRepeatedly(Return(true));
  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));

  {
    InSequence s;
    for (const auto& update_action_type : GetUpdateActionTypes()) {
      EXPECT_CALL(*processor_,
                  EnqueueAction(Pointee(
                      Property(&AbstractAction::Type, update_action_type))));
    }
    EXPECT_CALL(*processor_, StartProcessing());
  }

  attempter_.Update("", "", "", "", false, false, 0, false, false);
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::UpdateTestVerify,
                            base::Unretained(this)));
}

void UpdateAttempterTest::UpdateTestVerify() {
  EXPECT_EQ(0, attempter_.http_response_code());
  EXPECT_EQ(&attempter_, processor_->delegate());
  EXPECT_EQ(UpdateStatus::CHECKING_FOR_UPDATE, attempter_.status());
  loop_.BreakLoop();
}

void UpdateAttempterTest::RollbackTestStart(bool enterprise_rollback,
                                            bool valid_slot) {
  // Create a device policy so that we can change settings.
  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
  fake_system_state_.set_device_policy(device_policy.get());
  if (enterprise_rollback) {
    // We return an empty owner as this is an enterprise.
    EXPECT_CALL(*device_policy, GetOwner(_))
        .WillRepeatedly(DoAll(SetArgPointee<0>(string("")), Return(true)));
  } else {
    // We return a fake owner as this is an owned consumer device.
    EXPECT_CALL(*device_policy, GetOwner(_))
        .WillRepeatedly(DoAll(SetArgPointee<0>(string("fake.mail@fake.com")),
                              Return(true)));
  }

  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));

  if (valid_slot) {
    BootControlInterface::Slot rollback_slot = 1;
    LOG(INFO) << "Test Mark Bootable: "
              << BootControlInterface::SlotName(rollback_slot);
    fake_system_state_.fake_boot_control()->SetSlotBootable(rollback_slot,
                                                            true);
  }

  bool is_rollback_allowed = false;

  // We only allow rollback on devices that are not enterprise enrolled and
  // which have a valid slot to rollback to.
  if (!enterprise_rollback && valid_slot) {
    is_rollback_allowed = true;
  }

  if (is_rollback_allowed) {
    InSequence s;
    for (const auto& rollback_action_type : GetRollbackActionTypes()) {
      EXPECT_CALL(*processor_,
                  EnqueueAction(Pointee(
                      Property(&AbstractAction::Type, rollback_action_type))));
    }
    EXPECT_CALL(*processor_, StartProcessing());

    EXPECT_TRUE(attempter_.Rollback(true));
    loop_.PostTask(FROM_HERE,
                   base::Bind(&UpdateAttempterTest::RollbackTestVerify,
                              base::Unretained(this)));
  } else {
    EXPECT_FALSE(attempter_.Rollback(true));
    loop_.BreakLoop();
  }
}

void UpdateAttempterTest::RollbackTestVerify() {
  // Verifies the actions that were enqueued.
  EXPECT_EQ(&attempter_, processor_->delegate());
  EXPECT_EQ(UpdateStatus::ATTEMPTING_ROLLBACK, attempter_.status());
  EXPECT_EQ(0U, attempter_.install_plan_->partitions.size());
  EXPECT_EQ(attempter_.install_plan_->powerwash_required, true);
  loop_.BreakLoop();
}

TEST_F(UpdateAttempterTest, UpdateTest) {
  UpdateTestStart();
  loop_.Run();
}

TEST_F(UpdateAttempterTest, RollbackTest) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::RollbackTestStart,
                            base::Unretained(this),
                            false,
                            true));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, InvalidSlotRollbackTest) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::RollbackTestStart,
                            base::Unretained(this),
                            false,
                            false));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, EnterpriseRollbackTest) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::RollbackTestStart,
                            base::Unretained(this),
                            true,
                            true));
  loop_.Run();
}

void UpdateAttempterTest::PingOmahaTestStart() {
  EXPECT_CALL(*processor_,
              EnqueueAction(Pointee(Property(
                  &AbstractAction::Type, OmahaRequestAction::StaticType()))));
  EXPECT_CALL(*processor_, StartProcessing());
  attempter_.PingOmaha();
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, PingOmahaTest) {
  EXPECT_FALSE(attempter_.waiting_for_scheduled_check_);
  EXPECT_FALSE(attempter_.WasScheduleUpdatesCalled());
  // Disable scheduling of subsequnet checks; we're using the |DefaultPolicy| in
  // testing, which is more permissive than we want to handle here.
  attempter_.DisableScheduleUpdates();
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::PingOmahaTestStart,
                            base::Unretained(this)));
  brillo::MessageLoopRunMaxIterations(&loop_, 100);
  EXPECT_EQ(UpdateStatus::UPDATED_NEED_REBOOT, attempter_.status());
  EXPECT_TRUE(attempter_.WasScheduleUpdatesCalled());
}

TEST_F(UpdateAttempterTest, CreatePendingErrorEventTest) {
  MockAction action;
  const ErrorCode kCode = ErrorCode::kDownloadTransferError;
  attempter_.CreatePendingErrorEvent(&action, kCode);
  ASSERT_NE(nullptr, attempter_.error_event_.get());
  EXPECT_EQ(OmahaEvent::kTypeUpdateComplete, attempter_.error_event_->type);
  EXPECT_EQ(OmahaEvent::kResultError, attempter_.error_event_->result);
  EXPECT_EQ(
      static_cast<ErrorCode>(static_cast<int>(kCode) |
                             static_cast<int>(ErrorCode::kTestOmahaUrlFlag)),
      attempter_.error_event_->error_code);
}

TEST_F(UpdateAttempterTest, CreatePendingErrorEventResumedTest) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_resume = true;
  MockAction action;
  const ErrorCode kCode = ErrorCode::kInstallDeviceOpenError;
  attempter_.CreatePendingErrorEvent(&action, kCode);
  ASSERT_NE(nullptr, attempter_.error_event_.get());
  EXPECT_EQ(OmahaEvent::kTypeUpdateComplete, attempter_.error_event_->type);
  EXPECT_EQ(OmahaEvent::kResultError, attempter_.error_event_->result);
  EXPECT_EQ(
      static_cast<ErrorCode>(static_cast<int>(kCode) |
                             static_cast<int>(ErrorCode::kResumedFlag) |
                             static_cast<int>(ErrorCode::kTestOmahaUrlFlag)),
      attempter_.error_event_->error_code);
}

TEST_F(UpdateAttempterTest, P2PNotStartedAtStartupWhenNotEnabled) {
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  mock_p2p_manager.fake().SetP2PEnabled(false);
  EXPECT_CALL(mock_p2p_manager, EnsureP2PRunning()).Times(0);
  attempter_.UpdateEngineStarted();
}

TEST_F(UpdateAttempterTest, P2PNotStartedAtStartupWhenEnabledButNotSharing) {
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  mock_p2p_manager.fake().SetP2PEnabled(true);
  EXPECT_CALL(mock_p2p_manager, EnsureP2PRunning()).Times(0);
  attempter_.UpdateEngineStarted();
}

TEST_F(UpdateAttempterTest, P2PStartedAtStartupWhenEnabledAndSharing) {
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  mock_p2p_manager.fake().SetP2PEnabled(true);
  mock_p2p_manager.fake().SetCountSharedFilesResult(1);
  EXPECT_CALL(mock_p2p_manager, EnsureP2PRunning());
  attempter_.UpdateEngineStarted();
}

TEST_F(UpdateAttempterTest, P2PNotEnabled) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::P2PNotEnabledStart,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::P2PNotEnabledStart() {
  // If P2P is not enabled, check that we do not attempt housekeeping
  // and do not convey that P2P is to be used.
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  mock_p2p_manager.fake().SetP2PEnabled(false);
  EXPECT_CALL(mock_p2p_manager, PerformHousekeeping()).Times(0);
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_FALSE(actual_using_p2p_for_downloading_);
  EXPECT_FALSE(actual_using_p2p_for_sharing());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, P2PEnabledStartingFails) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::P2PEnabledStartingFailsStart,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::P2PEnabledStartingFailsStart() {
  // If P2P is enabled, but starting it fails ensure we don't do
  // any housekeeping and do not convey that P2P should be used.
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  mock_p2p_manager.fake().SetP2PEnabled(true);
  mock_p2p_manager.fake().SetEnsureP2PRunningResult(false);
  mock_p2p_manager.fake().SetPerformHousekeepingResult(false);
  EXPECT_CALL(mock_p2p_manager, PerformHousekeeping()).Times(0);
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_FALSE(actual_using_p2p_for_downloading());
  EXPECT_FALSE(actual_using_p2p_for_sharing());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, P2PEnabledHousekeepingFails) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(&UpdateAttempterTest::P2PEnabledHousekeepingFailsStart,
                 base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::P2PEnabledHousekeepingFailsStart() {
  // If P2P is enabled, starting it works but housekeeping fails, ensure
  // we do not convey P2P is to be used.
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  mock_p2p_manager.fake().SetP2PEnabled(true);
  mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
  mock_p2p_manager.fake().SetPerformHousekeepingResult(false);
  EXPECT_CALL(mock_p2p_manager, PerformHousekeeping());
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_FALSE(actual_using_p2p_for_downloading());
  EXPECT_FALSE(actual_using_p2p_for_sharing());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, P2PEnabled) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::P2PEnabledStart,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::P2PEnabledStart() {
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  // If P2P is enabled and starting it works, check that we performed
  // housekeeping and that we convey P2P should be used.
  mock_p2p_manager.fake().SetP2PEnabled(true);
  mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
  mock_p2p_manager.fake().SetPerformHousekeepingResult(true);
  EXPECT_CALL(mock_p2p_manager, PerformHousekeeping());
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_TRUE(actual_using_p2p_for_downloading());
  EXPECT_TRUE(actual_using_p2p_for_sharing());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, P2PEnabledInteractive) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::P2PEnabledInteractiveStart,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::P2PEnabledInteractiveStart() {
  MockP2PManager mock_p2p_manager;
  fake_system_state_.set_p2p_manager(&mock_p2p_manager);
  // For an interactive check, if P2P is enabled and starting it
  // works, check that we performed housekeeping and that we convey
  // P2P should be used for sharing but NOT for downloading.
  mock_p2p_manager.fake().SetP2PEnabled(true);
  mock_p2p_manager.fake().SetEnsureP2PRunningResult(true);
  mock_p2p_manager.fake().SetPerformHousekeepingResult(true);
  EXPECT_CALL(mock_p2p_manager, PerformHousekeeping());
  attempter_.Update("",
                    "",
                    "",
                    "",
                    false,
                    false,
                    /*rollback_allowed_milestones=*/0,
                    false,
                    /*interactive=*/true);
  EXPECT_FALSE(actual_using_p2p_for_downloading());
  EXPECT_TRUE(actual_using_p2p_for_sharing());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, ReadScatterFactorFromPolicy) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(&UpdateAttempterTest::ReadScatterFactorFromPolicyTestStart,
                 base::Unretained(this)));
  loop_.Run();
}

// Tests that the scatter_factor_in_seconds value is properly fetched
// from the device policy.
void UpdateAttempterTest::ReadScatterFactorFromPolicyTestStart() {
  int64_t scatter_factor_in_seconds = 36000;

  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
  fake_system_state_.set_device_policy(device_policy.get());

  EXPECT_CALL(*device_policy, GetScatterFactorInSeconds(_))
      .WillRepeatedly(
          DoAll(SetArgPointee<0>(scatter_factor_in_seconds), Return(true)));

  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));

  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());

  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, DecrementUpdateCheckCountTest) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(&UpdateAttempterTest::DecrementUpdateCheckCountTestStart,
                 base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::DecrementUpdateCheckCountTestStart() {
  // Tests that the scatter_factor_in_seconds value is properly fetched
  // from the device policy and is decremented if value > 0.
  int64_t initial_value = 5;
  FakePrefs fake_prefs;
  attempter_.prefs_ = &fake_prefs;

  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());

  EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));

  int64_t scatter_factor_in_seconds = 10;

  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
  fake_system_state_.set_device_policy(device_policy.get());

  EXPECT_CALL(*device_policy, GetScatterFactorInSeconds(_))
      .WillRepeatedly(
          DoAll(SetArgPointee<0>(scatter_factor_in_seconds), Return(true)));

  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));

  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());

  // Make sure the file still exists.
  EXPECT_TRUE(fake_prefs.Exists(kPrefsUpdateCheckCount));

  int64_t new_value;
  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &new_value));
  EXPECT_EQ(initial_value - 1, new_value);

  EXPECT_TRUE(
      attempter_.omaha_request_params_->update_check_count_wait_enabled());

  // However, if the count is already 0, it's not decremented. Test that.
  initial_value = 0;
  EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  EXPECT_TRUE(fake_prefs.Exists(kPrefsUpdateCheckCount));
  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &new_value));
  EXPECT_EQ(initial_value, new_value);

  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, NoScatteringDoneDuringManualUpdateTestStart) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(
          &UpdateAttempterTest::NoScatteringDoneDuringManualUpdateTestStart,
          base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::NoScatteringDoneDuringManualUpdateTestStart() {
  // Tests that no scattering logic is enabled if the update check
  // is manually done (as opposed to a scheduled update check)
  int64_t initial_value = 8;
  FakePrefs fake_prefs;
  attempter_.prefs_ = &fake_prefs;

  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
  fake_system_state_.set_prefs(&fake_prefs);

  EXPECT_TRUE(
      fake_prefs.SetInt64(kPrefsWallClockScatteringWaitPeriod, initial_value));
  EXPECT_TRUE(fake_prefs.SetInt64(kPrefsUpdateCheckCount, initial_value));

  // make sure scatter_factor is non-zero as scattering is disabled
  // otherwise.
  int64_t scatter_factor_in_seconds = 50;

  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
  fake_system_state_.set_device_policy(device_policy.get());

  EXPECT_CALL(*device_policy, GetScatterFactorInSeconds(_))
      .WillRepeatedly(
          DoAll(SetArgPointee<0>(scatter_factor_in_seconds), Return(true)));

  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));

  // Trigger an interactive check so we can test that scattering is disabled.
  attempter_.Update("",
                    "",
                    "",
                    "",
                    false,
                    false,
                    /*rollback_allowed_milestones=*/0,
                    false,
                    /*interactive=*/true);
  EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());

  // Make sure scattering is disabled for manual (i.e. user initiated) update
  // checks and all artifacts are removed.
  EXPECT_FALSE(
      attempter_.omaha_request_params_->wall_clock_based_wait_enabled());
  EXPECT_FALSE(fake_prefs.Exists(kPrefsWallClockScatteringWaitPeriod));
  EXPECT_EQ(0, attempter_.omaha_request_params_->waiting_period().InSeconds());
  EXPECT_FALSE(
      attempter_.omaha_request_params_->update_check_count_wait_enabled());
  EXPECT_FALSE(fake_prefs.Exists(kPrefsUpdateCheckCount));

  ScheduleQuitMainLoop();
}

void UpdateAttempterTest::SetUpStagingTest(const StagingSchedule& schedule,
                                           FakePrefs* prefs) {
  attempter_.prefs_ = prefs;
  fake_system_state_.set_prefs(prefs);

  int64_t initial_value = 8;
  EXPECT_TRUE(
      prefs->SetInt64(kPrefsWallClockScatteringWaitPeriod, initial_value));
  EXPECT_TRUE(prefs->SetInt64(kPrefsUpdateCheckCount, initial_value));
  attempter_.scatter_factor_ = TimeDelta::FromSeconds(20);

  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));
  fake_system_state_.set_device_policy(device_policy.get());
  EXPECT_CALL(*device_policy, GetDeviceUpdateStagingSchedule(_))
      .WillRepeatedly(DoAll(SetArgPointee<0>(schedule), Return(true)));

  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));
}

TEST_F(UpdateAttempterTest, StagingSetsPrefsAndTurnsOffScattering) {
  loop_.PostTask(
      FROM_HERE,
      base::Bind(
          &UpdateAttempterTest::StagingSetsPrefsAndTurnsOffScatteringStart,
          base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::StagingSetsPrefsAndTurnsOffScatteringStart() {
  // Tests that staging sets its prefs properly and turns off scattering.
  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
  FakePrefs fake_prefs;
  SetUpStagingTest(kValidStagingSchedule, &fake_prefs);

  attempter_.Update("", "", "", "", false, false, 0, false, false);
  // Check that prefs have the correct values.
  int64_t update_count;
  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &update_count));
  int64_t waiting_time_days;
  EXPECT_TRUE(fake_prefs.GetInt64(kPrefsWallClockStagingWaitPeriod,
                                  &waiting_time_days));
  EXPECT_GT(waiting_time_days, 0);
  // Update count should have been decremented.
  EXPECT_EQ(7, update_count);
  // Check that Omaha parameters were updated correctly.
  EXPECT_TRUE(
      attempter_.omaha_request_params_->update_check_count_wait_enabled());
  EXPECT_TRUE(
      attempter_.omaha_request_params_->wall_clock_based_wait_enabled());
  EXPECT_EQ(waiting_time_days,
            attempter_.omaha_request_params_->waiting_period().InDays());
  // Check class variables.
  EXPECT_EQ(waiting_time_days, attempter_.staging_wait_time_.InDays());
  EXPECT_EQ(kValidStagingSchedule, attempter_.staging_schedule_);
  // Check that scattering is turned off
  EXPECT_EQ(0, attempter_.scatter_factor_.InSeconds());
  EXPECT_FALSE(fake_prefs.Exists(kPrefsWallClockScatteringWaitPeriod));

  ScheduleQuitMainLoop();
}

void UpdateAttempterTest::CheckStagingOff() {
  // Check that all prefs were removed.
  EXPECT_FALSE(attempter_.prefs_->Exists(kPrefsUpdateCheckCount));
  EXPECT_FALSE(attempter_.prefs_->Exists(kPrefsWallClockScatteringWaitPeriod));
  EXPECT_FALSE(attempter_.prefs_->Exists(kPrefsWallClockStagingWaitPeriod));
  // Check that the Omaha parameters have the correct value.
  EXPECT_EQ(0, attempter_.omaha_request_params_->waiting_period().InDays());
  EXPECT_EQ(attempter_.omaha_request_params_->waiting_period(),
            attempter_.staging_wait_time_);
  EXPECT_FALSE(
      attempter_.omaha_request_params_->update_check_count_wait_enabled());
  EXPECT_FALSE(
      attempter_.omaha_request_params_->wall_clock_based_wait_enabled());
  // Check that scattering is turned off too.
  EXPECT_EQ(0, attempter_.scatter_factor_.InSeconds());
}

TEST_F(UpdateAttempterTest, StagingOffIfInteractive) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::StagingOffIfInteractiveStart,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::StagingOffIfInteractiveStart() {
  // Tests that staging is turned off when an interactive update is requested.
  fake_system_state_.fake_hardware()->SetIsOOBEComplete(Time::UnixEpoch());
  FakePrefs fake_prefs;
  SetUpStagingTest(kValidStagingSchedule, &fake_prefs);

  attempter_.Update(
      "", "", "", "", false, false, 0, false, /* interactive = */ true);
  CheckStagingOff();

  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, StagingOffIfOobe) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::StagingOffIfOobeStart,
                            base::Unretained(this)));
  loop_.Run();
}

void UpdateAttempterTest::StagingOffIfOobeStart() {
  // Tests that staging is turned off if OOBE hasn't been completed.
  fake_system_state_.fake_hardware()->SetIsOOBEEnabled(true);
  fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
  FakePrefs fake_prefs;
  SetUpStagingTest(kValidStagingSchedule, &fake_prefs);

  attempter_.Update(
      "", "", "", "", false, false, 0, false, /* interactive = */ true);
  CheckStagingOff();

  ScheduleQuitMainLoop();
}

// Checks that we only report daily metrics at most every 24 hours.
TEST_F(UpdateAttempterTest, ReportDailyMetrics) {
  FakeClock fake_clock;
  FakePrefs fake_prefs;

  fake_system_state_.set_clock(&fake_clock);
  fake_system_state_.set_prefs(&fake_prefs);

  Time epoch = Time::FromInternalValue(0);
  fake_clock.SetWallclockTime(epoch);

  // If there is no kPrefsDailyMetricsLastReportedAt state variable,
  // we should report.
  EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
  // We should not report again if no time has passed.
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // We should not report if only 10 hours has passed.
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(10));
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // We should not report if only 24 hours - 1 sec has passed.
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(24) -
                              TimeDelta::FromSeconds(1));
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // We should report if 24 hours has passed.
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(24));
  EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());

  // But then we should not report again..
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // .. until another 24 hours has passed
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(47));
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(48));
  EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // .. and another 24 hours
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(71));
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(72));
  EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // If the span between time of reporting and present time is
  // negative, we report. This is in order to reset the timestamp and
  // avoid an edge condition whereby a distant point in the future is
  // in the state variable resulting in us never ever reporting again.
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(71));
  EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());

  // In this case we should not update until the clock reads 71 + 24 = 95.
  // Check that.
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(94));
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
  fake_clock.SetWallclockTime(epoch + TimeDelta::FromHours(95));
  EXPECT_TRUE(attempter_.CheckAndReportDailyMetrics());
  EXPECT_FALSE(attempter_.CheckAndReportDailyMetrics());
}

TEST_F(UpdateAttempterTest, BootTimeInUpdateMarkerFile) {
  FakeClock fake_clock;
  fake_clock.SetBootTime(Time::FromTimeT(42));
  fake_system_state_.set_clock(&fake_clock);
  FakePrefs fake_prefs;
  fake_system_state_.set_prefs(&fake_prefs);
  attempter_.Init();

  Time boot_time;
  EXPECT_FALSE(attempter_.GetBootTimeAtUpdate(&boot_time));

  attempter_.WriteUpdateCompletedMarker();

  EXPECT_TRUE(attempter_.GetBootTimeAtUpdate(&boot_time));
  EXPECT_EQ(boot_time.ToTimeT(), 42);
}

TEST_F(UpdateAttempterTest, AnyUpdateSourceAllowedUnofficial) {
  fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
  EXPECT_TRUE(attempter_.IsAnyUpdateSourceAllowed());
}

TEST_F(UpdateAttempterTest, AnyUpdateSourceAllowedOfficialDevmode) {
  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(true);
  EXPECT_TRUE(attempter_.IsAnyUpdateSourceAllowed());
}

TEST_F(UpdateAttempterTest, AnyUpdateSourceDisallowedOfficialNormal) {
  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(false);
  EXPECT_FALSE(attempter_.IsAnyUpdateSourceAllowed());
}

// TODO(kimjae): Follow testing pattern with params for |CheckForInstall()|.
// When adding, remove older tests related to |CheckForInstall()|.
TEST_F(UpdateAttempterTest, CheckForInstallNotIdleFails) {
  for (const auto status : kNonIdleUpdateStatuses) {
    // GIVEN a non-idle status.
    attempter_.status_ = status;

    EXPECT_FALSE(attempter_.CheckForInstall({}, ""));
  }
}

TEST_F(UpdateAttempterTest, CheckForUpdateNotIdleFails) {
  for (const auto status : kNonIdleUpdateStatuses) {
    // GIVEN a non-idle status.
    cfu_params_.status = status;

    // THEN |ScheduleUpdates()| should not be called.
    cfu_params_.should_schedule_updates_be_called = false;
    // THEN result should indicate failure.
    cfu_params_.expected_result = false;

    TestCheckForUpdate();
  }
}

TEST_F(UpdateAttempterTest, CheckForUpdateOfficalBuildClearsSource) {
  // GIVEN a official build.

  // THEN we except forced app version + forced omaha url to be cleared.

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateUnofficialBuildChangesSource) {
  // GIVEN a nonofficial build with dev features enabled.
  cfu_params_.is_official_build = false;
  cfu_params_.are_dev_features_enabled = true;

  // THEN the forced app version + forced omaha url changes based on input.
  cfu_params_.expected_forced_app_version = cfu_params_.app_version;
  cfu_params_.expected_forced_omaha_url = cfu_params_.omaha_url;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateOfficialBuildScheduledAUTest) {
  // GIVEN a scheduled autest omaha url.
  cfu_params_.omaha_url = "autest-scheduled";

  // THEN forced app version is cleared.
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateUnofficialBuildScheduledAUTest) {
  // GIVEN a scheduled autest omaha url.
  cfu_params_.omaha_url = "autest-scheduled";
  // GIVEN a nonofficial build with dev features enabled.
  cfu_params_.is_official_build = false;
  cfu_params_.are_dev_features_enabled = true;

  // THEN forced app version changes based on input.
  cfu_params_.expected_forced_app_version = cfu_params_.app_version;
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateOfficialBuildAUTest) {
  // GIVEN a autest omaha url.
  cfu_params_.omaha_url = "autest";

  // THEN forced app version is cleared.
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateUnofficialBuildAUTest) {
  // GIVEN a autest omha url.
  cfu_params_.omaha_url = "autest";
  // GIVEN a nonofficial build with dev features enabled.
  cfu_params_.is_official_build = false;
  cfu_params_.are_dev_features_enabled = true;

  // THEN forced app version changes based on input.
  cfu_params_.expected_forced_app_version = cfu_params_.app_version;
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest,
       CheckForUpdateNonInteractiveOfficialBuildScheduledAUTest) {
  // GIVEN a scheduled autest omaha url.
  cfu_params_.omaha_url = "autest-scheduled";
  // GIVEN a noninteractive update.
  cfu_params_.flags = UpdateAttemptFlags::kFlagNonInteractive;

  // THEN forced app version is cleared.
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest,
       CheckForUpdateNonInteractiveUnofficialBuildScheduledAUTest) {
  // GIVEN a scheduled autest omaha url.
  cfu_params_.omaha_url = "autest-scheduled";
  // GIVEN a noninteractive update.
  cfu_params_.flags = UpdateAttemptFlags::kFlagNonInteractive;
  // GIVEN a nonofficial build with dev features enabled.
  cfu_params_.is_official_build = false;
  cfu_params_.are_dev_features_enabled = true;

  // THEN forced app version changes based on input.
  cfu_params_.expected_forced_app_version = cfu_params_.app_version;
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateNonInteractiveOfficialBuildAUTest) {
  // GIVEN a autest omaha url.
  cfu_params_.omaha_url = "autest";
  // GIVEN a noninteractive update.
  cfu_params_.flags = UpdateAttemptFlags::kFlagNonInteractive;

  // THEN forced app version is cleared.
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateNonInteractiveUnofficialBuildAUTest) {
  // GIVEN a autest omaha url.
  cfu_params_.omaha_url = "autest";
  // GIVEN a noninteractive update.
  cfu_params_.flags = UpdateAttemptFlags::kFlagNonInteractive;
  // GIVEN a nonofficial build with dev features enabled.
  cfu_params_.is_official_build = false;
  cfu_params_.are_dev_features_enabled = true;

  // THEN forced app version changes based on input.
  cfu_params_.expected_forced_app_version = cfu_params_.app_version;
  // THEN forced omaha url changes to default constant.
  cfu_params_.expected_forced_omaha_url = constants::kOmahaDefaultAUTestURL;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateMissingForcedCallback1) {
  // GIVEN a official build.
  // GIVEN forced callback is not set.
  attempter_.set_forced_update_pending_callback(nullptr);

  // THEN we except forced app version + forced omaha url to be cleared.
  // THEN |ScheduleUpdates()| should not be called.
  cfu_params_.should_schedule_updates_be_called = false;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForUpdateMissingForcedCallback2) {
  // GIVEN a nonofficial build with dev features enabled.
  cfu_params_.is_official_build = false;
  cfu_params_.are_dev_features_enabled = true;
  // GIVEN forced callback is not set.
  attempter_.set_forced_update_pending_callback(nullptr);

  // THEN the forced app version + forced omaha url changes based on input.
  cfu_params_.expected_forced_app_version = cfu_params_.app_version;
  cfu_params_.expected_forced_omaha_url = cfu_params_.omaha_url;
  // THEN |ScheduleUpdates()| should not be called.
  cfu_params_.should_schedule_updates_be_called = false;

  TestCheckForUpdate();
}

TEST_F(UpdateAttempterTest, CheckForInstallTest) {
  fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
  fake_system_state_.fake_hardware()->SetAreDevFeaturesEnabled(false);
  attempter_.CheckForInstall({}, "autest");
  EXPECT_EQ(constants::kOmahaDefaultAUTestURL, attempter_.forced_omaha_url());

  attempter_.CheckForInstall({}, "autest-scheduled");
  EXPECT_EQ(constants::kOmahaDefaultAUTestURL, attempter_.forced_omaha_url());

  attempter_.CheckForInstall({}, "http://omaha.phishing");
  EXPECT_EQ("", attempter_.forced_omaha_url());
}

TEST_F(UpdateAttempterTest, InstallSetsStatusIdle) {
  attempter_.CheckForInstall({}, "http://foo.bar");
  attempter_.status_ = UpdateStatus::DOWNLOADING;
  EXPECT_TRUE(attempter_.is_install_);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
  UpdateEngineStatus status;
  attempter_.GetStatus(&status);
  // Should set status to idle after an install operation.
  EXPECT_EQ(UpdateStatus::IDLE, status.status);
}

TEST_F(UpdateAttempterTest, RollbackAfterInstall) {
  attempter_.is_install_ = true;
  attempter_.Rollback(false);
  EXPECT_FALSE(attempter_.is_install_);
}

TEST_F(UpdateAttempterTest, UpdateAfterInstall) {
  attempter_.is_install_ = true;
  attempter_.CheckForUpdate("", "", UpdateAttemptFlags::kNone);
  EXPECT_FALSE(attempter_.is_install_);
}

TEST_F(UpdateAttempterTest, TargetVersionPrefixSetAndReset) {
  attempter_.CalculateUpdateParams(
      "", "", "", "1234", false, false, 4, false, false);
  EXPECT_EQ("1234",
            fake_system_state_.request_params()->target_version_prefix());

  attempter_.CalculateUpdateParams(
      "", "", "", "", false, 4, false, false, false);
  EXPECT_TRUE(
      fake_system_state_.request_params()->target_version_prefix().empty());
}

TEST_F(UpdateAttempterTest, RollbackAllowedSetAndReset) {
  attempter_.CalculateUpdateParams("",
                                   "",
                                   "",
                                   "1234",
                                   /*rollback_allowed=*/true,
                                   /*rollback_data_save_requested=*/false,
                                   /*rollback_allowed_milestones=*/4,
                                   false,
                                   false);
  EXPECT_TRUE(fake_system_state_.request_params()->rollback_allowed());
  EXPECT_EQ(4,
            fake_system_state_.request_params()->rollback_allowed_milestones());

  attempter_.CalculateUpdateParams("",
                                   "",
                                   "",
                                   "1234",
                                   /*rollback_allowed=*/false,
                                   /*rollback_data_save_requested=*/false,
                                   /*rollback_allowed_milestones=*/4,
                                   false,
                                   false);
  EXPECT_FALSE(fake_system_state_.request_params()->rollback_allowed());
  EXPECT_EQ(4,
            fake_system_state_.request_params()->rollback_allowed_milestones());
}

TEST_F(UpdateAttempterTest, UpdateDeferredByPolicyTest) {
  // Construct an OmahaResponseHandlerAction that has processed an InstallPlan,
  // but the update is being deferred by the Policy.
  OmahaResponseHandlerAction response_action(&fake_system_state_);
  response_action.install_plan_.version = "a.b.c.d";
  response_action.install_plan_.system_version = "b.c.d.e";
  response_action.install_plan_.payloads.push_back(
      {.size = 1234ULL, .type = InstallPayloadType::kFull});
  // Inform the UpdateAttempter that the OmahaResponseHandlerAction has
  // completed, with the deferred-update error code.
  attempter_.ActionCompleted(
      nullptr, &response_action, ErrorCode::kOmahaUpdateDeferredPerPolicy);
  {
    UpdateEngineStatus status;
    attempter_.GetStatus(&status);
    EXPECT_EQ(UpdateStatus::UPDATE_AVAILABLE, status.status);
    EXPECT_TRUE(attempter_.install_plan_);
    EXPECT_EQ(attempter_.install_plan_->version, status.new_version);
    EXPECT_EQ(attempter_.install_plan_->payloads[0].size,
              status.new_size_bytes);
  }
  // An "error" event should have been created to tell Omaha that the update is
  // being deferred.
  EXPECT_TRUE(nullptr != attempter_.error_event_);
  EXPECT_EQ(OmahaEvent::kTypeUpdateComplete, attempter_.error_event_->type);
  EXPECT_EQ(OmahaEvent::kResultUpdateDeferred, attempter_.error_event_->result);
  ErrorCode expected_code = static_cast<ErrorCode>(
      static_cast<int>(ErrorCode::kOmahaUpdateDeferredPerPolicy) |
      static_cast<int>(ErrorCode::kTestOmahaUrlFlag));
  EXPECT_EQ(expected_code, attempter_.error_event_->error_code);
  // End the processing
  attempter_.ProcessingDone(nullptr, ErrorCode::kOmahaUpdateDeferredPerPolicy);
  // Validate the state of the attempter.
  {
    UpdateEngineStatus status;
    attempter_.GetStatus(&status);
    EXPECT_EQ(UpdateStatus::REPORTING_ERROR_EVENT, status.status);
    EXPECT_EQ(response_action.install_plan_.version, status.new_version);
    EXPECT_EQ(response_action.install_plan_.payloads[0].size,
              status.new_size_bytes);
  }
}

TEST_F(UpdateAttempterTest, UpdateIsNotRunningWhenUpdateAvailable) {
  // Default construction for |waiting_for_scheduled_check_| is false.
  EXPECT_FALSE(attempter_.IsBusyOrUpdateScheduled());
  // Verify in-progress update with UPDATE_AVAILABLE is running
  attempter_.status_ = UpdateStatus::UPDATE_AVAILABLE;
  EXPECT_TRUE(attempter_.IsBusyOrUpdateScheduled());
}

TEST_F(UpdateAttempterTest, UpdateAttemptFlagsCachedAtUpdateStart) {
  attempter_.SetUpdateAttemptFlags(UpdateAttemptFlags::kFlagRestrictDownload);

  UpdateCheckParams params = {.updates_enabled = true};
  attempter_.OnUpdateScheduled(EvalStatus::kSucceeded, params);

  EXPECT_EQ(UpdateAttemptFlags::kFlagRestrictDownload,
            attempter_.GetCurrentUpdateAttemptFlags());
}

TEST_F(UpdateAttempterTest, RollbackNotAllowed) {
  UpdateCheckParams params = {.updates_enabled = true,
                              .rollback_allowed = false};
  attempter_.OnUpdateScheduled(EvalStatus::kSucceeded, params);
  EXPECT_FALSE(fake_system_state_.request_params()->rollback_allowed());
}

TEST_F(UpdateAttempterTest, RollbackAllowed) {
  UpdateCheckParams params = {.updates_enabled = true,
                              .rollback_allowed = true};
  attempter_.OnUpdateScheduled(EvalStatus::kSucceeded, params);
  EXPECT_TRUE(fake_system_state_.request_params()->rollback_allowed());
}

TEST_F(UpdateAttempterTest, InteractiveUpdateUsesPassedRestrictions) {
  attempter_.SetUpdateAttemptFlags(UpdateAttemptFlags::kFlagRestrictDownload);

  attempter_.CheckForUpdate("", "", UpdateAttemptFlags::kNone);
  EXPECT_EQ(UpdateAttemptFlags::kNone,
            attempter_.GetCurrentUpdateAttemptFlags());
}

TEST_F(UpdateAttempterTest, NonInteractiveUpdateUsesSetRestrictions) {
  attempter_.SetUpdateAttemptFlags(UpdateAttemptFlags::kNone);

  // This tests that when CheckForUpdate() is called with the non-interactive
  // flag set, that it doesn't change the current UpdateAttemptFlags.
  attempter_.CheckForUpdate("",
                            "",
                            UpdateAttemptFlags::kFlagNonInteractive |
                                UpdateAttemptFlags::kFlagRestrictDownload);
  EXPECT_EQ(UpdateAttemptFlags::kNone,
            attempter_.GetCurrentUpdateAttemptFlags());
}

void UpdateAttempterTest::ResetRollbackHappenedStart(bool is_consumer,
                                                     bool is_policy_loaded,
                                                     bool expected_reset) {
  EXPECT_CALL(*fake_system_state_.mock_payload_state(), GetRollbackHappened())
      .WillRepeatedly(Return(true));
  auto mock_policy_provider =
      std::make_unique<NiceMock<policy::MockPolicyProvider>>();
  EXPECT_CALL(*mock_policy_provider, IsConsumerDevice())
      .WillRepeatedly(Return(is_consumer));
  EXPECT_CALL(*mock_policy_provider, device_policy_is_loaded())
      .WillRepeatedly(Return(is_policy_loaded));
  const policy::MockDevicePolicy device_policy;
  EXPECT_CALL(*mock_policy_provider, GetDevicePolicy())
      .WillRepeatedly(ReturnRef(device_policy));
  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
              SetRollbackHappened(false))
      .Times(expected_reset ? 1 : 0);
  attempter_.policy_provider_ = std::move(mock_policy_provider);
  attempter_.Update("", "", "", "", false, false, 0, false, false);
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest, ResetRollbackHappenedOobe) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::ResetRollbackHappenedStart,
                            base::Unretained(this),
                            /*is_consumer=*/false,
                            /*is_policy_loaded=*/false,
                            /*expected_reset=*/false));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, ResetRollbackHappenedConsumer) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::ResetRollbackHappenedStart,
                            base::Unretained(this),
                            /*is_consumer=*/true,
                            /*is_policy_loaded=*/false,
                            /*expected_reset=*/true));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, ResetRollbackHappenedEnterprise) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::ResetRollbackHappenedStart,
                            base::Unretained(this),
                            /*is_consumer=*/false,
                            /*is_policy_loaded=*/true,
                            /*expected_reset=*/true));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, SetRollbackHappenedRollback) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_rollback = true;

  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
              SetRollbackHappened(true))
      .Times(1);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

TEST_F(UpdateAttempterTest, SetRollbackHappenedNotRollback) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_rollback = false;

  EXPECT_CALL(*fake_system_state_.mock_payload_state(),
              SetRollbackHappened(true))
      .Times(0);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

TEST_F(UpdateAttempterTest, RollbackMetricsRollbackSuccess) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_rollback = true;
  attempter_.install_plan_->version = kRollbackVersion;

  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseRollbackMetrics(true, kRollbackVersion))
      .Times(1);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

TEST_F(UpdateAttempterTest, RollbackMetricsNotRollbackSuccess) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_rollback = false;
  attempter_.install_plan_->version = kRollbackVersion;

  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseRollbackMetrics(_, _))
      .Times(0);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

TEST_F(UpdateAttempterTest, RollbackMetricsRollbackFailure) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_rollback = true;
  attempter_.install_plan_->version = kRollbackVersion;

  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseRollbackMetrics(false, kRollbackVersion))
      .Times(1);
  MockAction action;
  attempter_.CreatePendingErrorEvent(&action, ErrorCode::kRollbackNotPossible);
  attempter_.ProcessingDone(nullptr, ErrorCode::kRollbackNotPossible);
}

TEST_F(UpdateAttempterTest, RollbackMetricsNotRollbackFailure) {
  attempter_.install_plan_.reset(new InstallPlan);
  attempter_.install_plan_->is_rollback = false;
  attempter_.install_plan_->version = kRollbackVersion;

  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseRollbackMetrics(_, _))
      .Times(0);
  MockAction action;
  attempter_.CreatePendingErrorEvent(&action, ErrorCode::kRollbackNotPossible);
  attempter_.ProcessingDone(nullptr, ErrorCode::kRollbackNotPossible);
}

TEST_F(UpdateAttempterTest, TimeToUpdateAppliedMetricFailure) {
  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseUpdateSeenToDownloadDays(_, _))
      .Times(0);
  attempter_.ProcessingDone(nullptr, ErrorCode::kOmahaUpdateDeferredPerPolicy);
}

TEST_F(UpdateAttempterTest, TimeToUpdateAppliedOnNonEnterprise) {
  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  fake_system_state_.set_device_policy(device_policy.get());
  // Make device policy return that this is not enterprise enrolled
  EXPECT_CALL(*device_policy, IsEnterpriseEnrolled()).WillOnce(Return(false));

  // Ensure that the metric is not recorded.
  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseUpdateSeenToDownloadDays(_, _))
      .Times(0);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

TEST_F(UpdateAttempterTest,
       TimeToUpdateAppliedWithTimeRestrictionMetricSuccess) {
  constexpr int kDaysToUpdate = 15;
  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  fake_system_state_.set_device_policy(device_policy.get());
  // Make device policy return that this is enterprise enrolled
  EXPECT_CALL(*device_policy, IsEnterpriseEnrolled()).WillOnce(Return(true));
  // Pretend that there's a time restriction policy in place
  EXPECT_CALL(*device_policy, GetDisallowedTimeIntervals(_))
      .WillOnce(Return(true));

  FakePrefs fake_prefs;
  Time update_first_seen_at = Time::Now();
  fake_prefs.SetInt64(kPrefsUpdateFirstSeenAt,
                      update_first_seen_at.ToInternalValue());

  FakeClock fake_clock;
  Time update_finished_at =
      update_first_seen_at + TimeDelta::FromDays(kDaysToUpdate);
  fake_clock.SetWallclockTime(update_finished_at);

  fake_system_state_.set_clock(&fake_clock);
  fake_system_state_.set_prefs(&fake_prefs);

  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseUpdateSeenToDownloadDays(true, kDaysToUpdate))
      .Times(1);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

TEST_F(UpdateAttempterTest,
       TimeToUpdateAppliedWithoutTimeRestrictionMetricSuccess) {
  constexpr int kDaysToUpdate = 15;
  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  fake_system_state_.set_device_policy(device_policy.get());
  // Make device policy return that this is enterprise enrolled
  EXPECT_CALL(*device_policy, IsEnterpriseEnrolled()).WillOnce(Return(true));
  // Pretend that there's no time restriction policy in place
  EXPECT_CALL(*device_policy, GetDisallowedTimeIntervals(_))
      .WillOnce(Return(false));

  FakePrefs fake_prefs;
  Time update_first_seen_at = Time::Now();
  fake_prefs.SetInt64(kPrefsUpdateFirstSeenAt,
                      update_first_seen_at.ToInternalValue());

  FakeClock fake_clock;
  Time update_finished_at =
      update_first_seen_at + TimeDelta::FromDays(kDaysToUpdate);
  fake_clock.SetWallclockTime(update_finished_at);

  fake_system_state_.set_clock(&fake_clock);
  fake_system_state_.set_prefs(&fake_prefs);

  EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
              ReportEnterpriseUpdateSeenToDownloadDays(false, kDaysToUpdate))
      .Times(1);
  attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}

void UpdateAttempterTest::UpdateToQuickFixBuildStart(bool set_token) {
  // Tests that checks if |device_quick_fix_build_token| arrives when
  // policy is set and the device is enterprise enrolled based on |set_token|.
  string token = set_token ? "some_token" : "";
  auto device_policy = std::make_unique<policy::MockDevicePolicy>();
  fake_system_state_.set_device_policy(device_policy.get());
  EXPECT_CALL(*device_policy, LoadPolicy()).WillRepeatedly(Return(true));

  if (set_token)
    EXPECT_CALL(*device_policy, GetDeviceQuickFixBuildToken(_))
        .WillOnce(DoAll(SetArgPointee<0>(token), Return(true)));
  else
    EXPECT_CALL(*device_policy, GetDeviceQuickFixBuildToken(_))
        .WillOnce(Return(false));
  attempter_.policy_provider_.reset(
      new policy::PolicyProvider(std::move(device_policy)));
  attempter_.Update("", "", "", "", false, false, 0, false, false);

  EXPECT_EQ(token, attempter_.omaha_request_params_->autoupdate_token());
  ScheduleQuitMainLoop();
}

TEST_F(UpdateAttempterTest,
       QuickFixTokenWhenDeviceIsEnterpriseEnrolledAndPolicyIsSet) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::UpdateToQuickFixBuildStart,
                            base::Unretained(this),
                            /*set_token=*/true));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, EmptyQuickFixToken) {
  loop_.PostTask(FROM_HERE,
                 base::Bind(&UpdateAttempterTest::UpdateToQuickFixBuildStart,
                            base::Unretained(this),
                            /*set_token=*/false));
  loop_.Run();
}

TEST_F(UpdateAttempterTest, ScheduleUpdateSpamHandlerTest) {
  EXPECT_CALL(mock_update_manager_, AsyncPolicyRequestUpdateCheckAllowed(_, _))
      .Times(1);
  EXPECT_TRUE(attempter_.ScheduleUpdates());
  // Now there is an update scheduled which means that all subsequent
  // |ScheduleUpdates()| should fail.
  EXPECT_FALSE(attempter_.ScheduleUpdates());
  EXPECT_FALSE(attempter_.ScheduleUpdates());
  EXPECT_FALSE(attempter_.ScheduleUpdates());
}

// Critical tests to always make sure that an update is scheduled. The following
// unittest(s) try and cover the correctness in synergy between
// |UpdateAttempter| and |UpdateManager|. Also it is good to remember the
// actions that happen in the flow when |UpdateAttempter| get callbacked on
// |OnUpdateScheduled()| -> (various cases which leads to) -> |ProcessingDone()|
void UpdateAttempterTest::TestOnUpdateScheduled() {
  // Setup
  attempter_.SetWaitingForScheduledCheck(true);
  attempter_.DisableUpdate();
  attempter_.DisableScheduleUpdates();

  // Invocation
  attempter_.OnUpdateScheduled(ous_params_.status, ous_params_.params);

  // Verify
  EXPECT_EQ(ous_params_.exit_status, attempter_.status());
  EXPECT_EQ(ous_params_.should_schedule_updates_be_called,
            attempter_.WasScheduleUpdatesCalled());
  EXPECT_EQ(ous_params_.should_update_be_called, attempter_.WasUpdateCalled());
}

TEST_F(UpdateAttempterTest, OnUpdatesScheduledFailed) {
  // GIVEN failed status.

  // THEN update should be scheduled.
  ous_params_.should_schedule_updates_be_called = true;

  TestOnUpdateScheduled();
}

TEST_F(UpdateAttempterTest, OnUpdatesScheduledAskMeAgainLater) {
  // GIVEN ask me again later status.
  ous_params_.status = EvalStatus::kAskMeAgainLater;

  // THEN update should be scheduled.
  ous_params_.should_schedule_updates_be_called = true;

  TestOnUpdateScheduled();
}

TEST_F(UpdateAttempterTest, OnUpdatesScheduledContinue) {
  // GIVEN continue status.
  ous_params_.status = EvalStatus::kContinue;

  // THEN update should be scheduled.
  ous_params_.should_schedule_updates_be_called = true;

  TestOnUpdateScheduled();
}

TEST_F(UpdateAttempterTest, OnUpdatesScheduledSucceededButUpdateDisabledFails) {
  // GIVEN updates disabled.
  ous_params_.params = {.updates_enabled = false};
  // GIVEN succeeded status.
  ous_params_.status = EvalStatus::kSucceeded;

  // THEN update should not be scheduled.

  TestOnUpdateScheduled();
}

TEST_F(UpdateAttempterTest, OnUpdatesScheduledSucceeded) {
  // GIVEN updates enabled.
  ous_params_.params = {.updates_enabled = true};
  // GIVEN succeeded status.
  ous_params_.status = EvalStatus::kSucceeded;

  // THEN update should be called indicating status change.
  ous_params_.exit_status = UpdateStatus::CHECKING_FOR_UPDATE;
  ous_params_.should_update_be_called = true;

  TestOnUpdateScheduled();
}

}  // namespace chromeos_update_engine
